> ## Documentation Index
> Fetch the complete documentation index at: https://docs.postonce.to/llms.txt
> Use this file to discover all available pages before exploring further.

# Partner integration

> Let your own users connect YouTube, TikTok and Instagram and publish from your product through PostOnce.

The Partner API is for products that publish on behalf of their own users (your "end users"). PostOnce enables it per account; contact [support@postonce.to](mailto:support@postonce.to) to become a partner. Partner connections support YouTube, TikTok and Instagram.

Your end users never create a PostOnce account. They click connect in your product, approve on the platform's own consent screen, and land back in your product.

<Note>
  Keep your API key on your server. Every request below is made from your
  backend.
</Note>

## 1. Connect an end user's account

Call the connect endpoint with your own user id and an allowed redirect URL. Allowed redirect URLs are configured for your partner account; the value must match one of them exactly (scheme, host and path).

```bash theme={null}
curl -s \
  -H "Authorization: Bearer po_live_xxxxx_xxxxx" \
  -H "Content-Type: application/json" \
  -X POST https://postonce.to/api/public/v1/accounts/connect/tiktok \
  -d '{
    "external_user_id": "user_8f21",
    "redirect_url": "https://app.example.com/integrations/postonce/callback"
  }'
```

```json theme={null}
{
  "data": {
    "authorization_url": "https://www.tiktok.com/v2/auth/authorize/?...",
    "mode": "oauth",
    "platform": "tiktok",
    "external_user_id": "user_8f21"
  }
}
```

Send the end user's browser to `authorization_url` within 5 minutes. After they approve, PostOnce redirects them to your `redirect_url` with:

| Parameter | Value |
| - | - |
| `status` | `connected` or `error` |
| `account_id` | The PostOnce account id (when connected) |
| `platform` | `youtube`, `tiktok` or `instagram` |
| `external_user_id` | The id you sent |
| `error` | An error code (when `status=error`), for example `access_denied` |

Instagram requires a Business or Creator account. Where end users connect YouTube, link to the [YouTube Terms of Service](https://www.youtube.com/t/terms) and the [Google Privacy Policy](https://policies.google.com/privacy).

## 2. List an end user's accounts

```bash theme={null}
curl -s \
  -H "Authorization: Bearer po_live_xxxxx_xxxxx" \
  "https://postonce.to/api/public/v1/accounts?external_user_id=user_8f21"
```

Each account includes `external_user_id` and `status`. An account with status `auth_required` needs the end user to connect again.

## 3. Build a compliant TikTok posting screen

TikTok requires the screen your end users post from to follow its [Content Sharing Guidelines](https://developers.tiktok.com/doc/content-sharing-guidelines). Load the creator's current settings right before showing the screen:

```bash theme={null}
curl -s \
  -H "Authorization: Bearer po_live_xxxxx_xxxxx" \
  https://postonce.to/api/public/v1/accounts/ACCOUNT_ID/tiktok/creator-info
```

```json theme={null}
{
  "data": {
    "account_id": "…",
    "creator_nickname": "Kiki Makes",
    "creator_username": "kiki.makes",
    "creator_avatar_url": "https://…",
    "privacy_level_options": [
      "PUBLIC_TO_EVERYONE",
      "MUTUAL_FOLLOW_FRIENDS",
      "SELF_ONLY"
    ],
    "comment_disabled": false,
    "duet_disabled": true,
    "stitch_disabled": false,
    "max_video_post_duration_sec": 600
  }
}
```

Your posting screen must:

* Show `creator_nickname`, so the end user knows which account receives the video.
* Offer a privacy dropdown built from `privacy_level_options`, with no default selected.
* Offer Comment, Duet and Stitch toggles, all off by default, greyed out when the matching `*_disabled` value is `true`.
* Offer a "Disclose video content" toggle (off by default) with "Your brand" and "Branded content" options. Branded content can't be private.
* Show "By posting, you agree to TikTok's Music Usage Confirmation" (plus the Branded Content Policy when branded content is selected).
* Show a preview, and start the upload only after the end user explicitly confirms.

Pass the end user's choices as TikTok `platform_options`:

| Option | Values |
| - | - |
| `privacy` | `public`, `friends`, `followers`, `private` |
| `comments`, `duet`, `stitch` | `true` to allow, `false` to disable |
| `commercialContent` | `true` when the disclosure toggle is on |
| `yourBrand`, `brandedContent` | `true` for the selected disclosure option(s) |

## 4. Publish for an end user

Include `external_user_id` so PostOnce rejects any target that belongs to a different end user (`403 account_not_owned_by_user`).

```bash theme={null}
curl -s \
  -H "Authorization: Bearer po_live_xxxxx_xxxxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: video-55812" \
  -X POST https://postonce.to/api/public/v1/posts \
  -d '{
    "external_user_id": "user_8f21",
    "external_id": "video-55812",
    "content": "Three stoic habits in 30 seconds",
    "media": [{ "url": "https://cdn.example.com/55812.mp4" }],
    "targets": [
      {
        "account_id": "TIKTOK_ACCOUNT_ID",
        "platform_options": { "privacy": "public", "comments": true, "duet": false, "stitch": false, "commercialContent": false }
      },
      { "account_id": "YOUTUBE_ACCOUNT_ID" }
    ]
  }'
```

Add `publish_at` to schedule instead of publishing now. Poll `GET /v1/posts/{id}` for per-target status, and list an end user's posts with `GET /v1/posts?external_user_id=user_8f21`.

## Billing

Billing is per successful post: one video published to one account. Failed posts and retries are free. Choose Pay as you go or Growth in the Developers page of your PostOnce dashboard; usage is billed monthly.
