Source: https://developers.tokportal.com/ad-code-request/
Markdown: https://developers.tokportal.com/ad-code-request.md

# Ad Code Request

Request an **ad code** for one finalized video so you can run it as a paid ad from your own ad account. On TikTok this is a **Spark Code**; on Instagram it is a **partner / branded-content code**.

The assigned account manager generates the code on the account and submits it. You then retrieve it by polling the same endpoint.

**Cost:** 7 credits per ad code.

> **CAUTION: Rules to know before running a Spark Ad**
>
> - **The caption is locked** once the Spark Code is generated. Make sure the video's caption is final before requesting the code.
> - **The sound must be original audio or from TikTok's Commercial Music Library.** Videos using trending/licensed sounds get muted or rejected when run as ads.
> - The post can stay **"Show only in ads"** (hidden from the profile) if needed.

## Request an Ad Code

```
POST /videos/:id/ad-code-request
```

The `:id` is a **video ID** (the finalized video you want to promote), not a bundle ID. Use [`GET /accounts/:id/analytics/videos`](https://developers.tokportal.com/analytics#post-analytics-by-account) or your finalized orders to find video IDs.

### Prerequisites

- The video must be **finalized**
- The video must be on **TikTok or Instagram**
- The video must have a **live post link**
- The saved account must have active TokPortal Coverage or be permanently grandfathered
- If an active order exists, its manager is authoritative and must still be an active Account Manager
- TokPortal walks completed orders newest-first and assigns the first historical manager who is still active
- The request appears directly in that manager's Calendar. `Accept & start` acknowledges the assigned work; it is not a marketplace claim
- Cancelled orders are never used as fallback
- No other ad code request can be **in progress** for the same video
- You need at least **7 credits** in your balance

A completed bundle remains eligible without a delivery-age limit. Coverage validation, manager assignment, the 7-credit debit, and request creation commit atomically. A failed prerequisite never creates a request or debit. If Coverage later pauses or lapses, unfinished work is withheld from the manager queue and does not become late; reactivation restores it through the account-level resume flow.

### Request Body

| Field  | Type   | Required | Description                                                                          |
| ------ | ------ | -------- | ------------------------------------------------------------------------------------ |
| `note` | string | No       | Optional message to your manager (max 500 chars), e.g. the campaign this code is for |

The target network is always taken from the video itself. There is no `platform` request field — it was removed from the public schema because it was never read. Requests that still send it are unaffected: the name simply comes back in `meta.ignored_fields`.

```bash
curl -X POST https://app.tokportal.com/api/ext/videos/{video_id}/ad-code-request \
  -H "X-API-Key: sk_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "note": "For our Q3 Spark Ads campaign"
  }'
```

### Response (201)

```json
{
  "data": {
    "ad_code_request_id": "uuid",
    "video_id": "uuid",
    "status": "pending",
    "platform": "tiktok",
    "code": null,
    "note": "For our Q3 Spark Ads campaign",
    "created_at": "2026-06-16T10:22:00Z"
  },
  "credits_charged": 7,
  "credits_remaining": 1240
}
```

## Get / Poll the Code

```
GET /videos/:id/ad-code-request
```

Returns the latest ad code request for the video. The `code` field stays `null` until your manager submits it (status `in_review`) or it is delivered (status `finalized`). Poll this endpoint until `code` is present.

```bash
curl https://app.tokportal.com/api/ext/videos/{video_id}/ad-code-request \
  -H "X-API-Key: sk_xxx"
```

### Response (200) — once the manager has submitted the code

```json
{
  "data": {
    "ad_code_request_id": "uuid",
    "video_id": "uuid",
    "status": "in_review",
    "platform": "tiktok",
    "code": "#TTSpark_AbC123XyZ",
    "note": "For our Q3 Spark Ads campaign",
    "created_at": "2026-06-16T10:22:00Z",
    "submitted_at": "2026-06-16T14:05:00Z",
    "delivered_at": null
  }
}
```

If no request exists for the video, `data` is `null`.

### Errors

| Code                           | Status | When                                                                                                                                                                        |
| ------------------------------ | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `AD_CODE_VIDEO_NOT_FOUND`      | 404    | Video ID not found                                                                                                                                                          |
| `AD_CODE_NOT_OWNED`            | 403    | Video belongs to another user                                                                                                                                               |
| `AD_CODE_VIDEO_NOT_FINALIZED`  | 409    | Video is not finalized                                                                                                                                                      |
| `AD_CODE_NO_POST_URL`          | 409    | The finalized video has no live post link                                                                                                                                   |
| `MANAGED_ACCOUNT_TASK_BLOCKED` | 409    | Coverage is inactive or the account is detached, banned, missing Coverage, or otherwise unavailable. Fetch the account Coverage state and reactivate only when recoverable. |
| `AD_CODE_NO_CM`                | 409    | The active order has no eligible active manager                                                                                                                             |
| `AD_CODE_NO_ORDER`             | 409    | No non-cancelled support order or active historical manager can be resolved                                                                                                 |
| `AD_CODE_ALREADY_EXISTS`       | 409    | Another ad-code request is already open                                                                                                                                     |
| `INSUFFICIENT_CREDITS`         | 402    | Fewer than 7 credits are available                                                                                                                                          |

## Using the code (in TikTok Ads Manager)

Once you have the Spark Code, run the video as a native ad from your own ad account:

1. TikTok Ads Manager → **Creative library → Spark Ads posts**.
2. Click **Apply for authorization** and paste the code.
3. The post appears in your library with its authorization period.
4. When creating an ad, pick the authorized post, add your CTA + landing URL, and publish.

If a delivered code does not work, report it from the TokPortal dashboard. The
public API currently supports creating and polling ad-code requests; it does not
expose the dashboard-only correction transition. Do not call the internal
`/api/ad-code-requests/{id}` route with a public API key.

## Ad Code Statuses

| Status                | Meaning                                                                         |
| --------------------- | ------------------------------------------------------------------------------- |
| `pending`             | Request created, waiting for the manager                                        |
| `accepted`            | Manager acknowledged the request                                                |
| `in_review`           | Manager submitted the code — **`code` is now readable**                         |
| `pending_corrections` | A correction was requested; the manager will re-submit                          |
| `finalized`           | Delivered and confirmed (manager is paid). Terminal                             |
| `cancelled`           | Cancelled (e.g. the manager could not generate it); your 7 credits are refunded |

> **TIP: Poll until delivered**
> After `POST`, poll `GET /videos/:id/ad-code-request` every few seconds. As soon as `status` is `in_review` and `code` is non-null, you can use the Spark Code in TikTok Ads Manager.

> **NOTE: Platform terminology**
> TokPortal returns the same request shape for TikTok Spark Codes and Instagram partner / branded-content codes. The `platform` field **on the response** identifies the target network; it is derived from the video and cannot be set in the request.
