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

# Kwai for Business as a data source

> Bring your Kwai for Business advertising reports to Nekt.

Kwai for Business is the advertising platform of the Kwai short-video app. Its Marketing API gives advertisers and agencies their ad accounts and daily performance reports: spend, impressions, clicks, video plays and conversions by account, campaign, ad set, creative, video, country and operating system. Nekt reads these reports so you can analyze them next to your other marketing data.

## Before you start: create your Kwai developer app

Nekt connects with a developer app that **you** create in the Kwai Business Center. Kwai gives report access to direct advertisers and agencies without any e-mail exchange. You need an administrator of your Business Center for steps 1 and 2.

1. **Create a developer user.** On the [Kwai Business Center](https://business.kwai.com/uc?targetServer=account#/login) login page, click **Sign Up** and register a user with a company e-mail. Use a new user: an existing user with another role (for example, optimizer) cannot become a developer.
2. **Give it the Developer role.** An administrator opens **Personnel management**, clicks **Add New Personnel**, enters the e-mail registered in step 1, picks the **same team as the administrator** and assigns the character **Developer**. A developer user cannot be changed to another role later, and the other way round.
3. **Create the developer app.** Logged in as the developer user, apply to become a developer and fill in: API role (**Direct advertiser** or **Agency**), the access level suggested by the Business Center, an app name and a **Callback URL**. The callback cannot be changed later; any address you control works, for example your company website, because you only need to copy the code Kwai appends to it. Each developer can create only one app.
4. **Copy the app details.** The app page shows the **APP ID** (the Client ID), the **Secret ID** (the Client Secret) and the **Authorization URL**.
5. **Authorize the app.** Open the Authorization URL in the same browser where you are logged in to the Business Center and confirm. The browser goes to your callback address with `?code=...` at the end: copy the value of `code`.
6. **Get the refresh token.** In the same browser, open the address below, replacing the four values in capitals, and copy the `refresh_token` from the answer:

   `https://business.kwai.com/oauth/token?grant_type=authorization_code&code=CODE&client_id=APP_ID&client_secret=SECRET_ID&redirect_uri=CALLBACK_URL`

   The answer also carries an `access_token`, which Nekt does not need. The authorization code is valid only once and for a short time: if the address answers with an error, repeat step 5.
7. **Find your Agent ID or Corp ID.** Nekt uses it to list the advertiser accounts of your Business Center.
   * **Agencies** use their **Agent ID**: open the Business Center and look at the address bar, which shows `agentId=` followed by the number.
   * **Direct advertisers** use their **Corp ID**: open the Business Center of your company and look for `corpId=` in the address bar. If it does not appear there, ask your Kwai sales contact for the Corp ID of your company (Kwai also sends it as `corpId` when it sets up API access by e-mail).

> [!NOTE]
>
> Kwai renews the refresh token every time it is used, and Nekt keeps the newest one automatically. Paste a refresh token in Nekt only once per authorization: if you need a new one (for example, after the token expires, about 6 to 12 months without use), repeat steps 5 and 6 and paste the new token in the source configuration. Do not use the same refresh token in another tool, because the first one to use it invalidates it for the other.

## Configuring Kwai for Business as a Source

In the [Sources](https://app.nekt.ai/sources) tab, click on the "Add source" button located on the top right of your screen. Then, select the Kwai for Business option from the list of connectors.

Click **Next** and you'll be prompted to add your access.

### 1. Add account access

The following configurations are available:

* **Client ID**: the APP ID of your developer app.
* **Client Secret**: the Secret ID of your developer app.
* **Refresh Token**: the refresh token from step 6 above.
* **Agent ID**: your agency ID, for agency developers. Fill in either Agent ID or Corp ID.
* **Corp ID**: your corporation ID, for direct advertisers. Fill in either Agent ID or Corp ID.
* **Start Date**: the earliest report day to sync. Kwai keeps report history from the first impression of each account.

Advanced settings:

* **Account IDs**: comma-separated advertiser account IDs to sync. Leave empty to sync every account of your agency or corporation.
* **Report Lookback Days**: (Default: 7) days read again on every run. Kwai counts each conversion on the day it happens (not on the day of the click), and some events reach Kwai late, for example delayed app or pixel postbacks. The lookback refreshes the recent days that late events can still change.
* **Report Time Zone**: (Default: UTC-3) the UTC offset that defines the report days. Kwai accepts UTC-6 to UTC+8. If you change it after the first sync, run a full sync, because the day boundaries of the rows already loaded change.
* **App IDs**: comma-separated Kwai for Business App IDs of the apps you promote. Needed only by the **App Performance by Country** table. An App ID added after the first sync only gets the last **Report Lookback Days** of history; run a full sync of that table to load its past.

Once you're done, click **Next**.

### 2. Select streams

Choose which data streams you want to sync. For faster extractions, select only the streams that are relevant to your analysis. Some streams are not selected by default because they need extra permissions or settings (see the table below).

> Tip: The stream can be found more easily by typing its name.

Select the streams and click **Next**.

### 3. Configure data streams

Customize how you want your data to appear in your catalog. Select the desired layer where the data will be placed, a folder to organize it inside the layer, a name for each table (which will effectively contain the fetched data) and the type of sync.

* **Layer**: choose between the existing layers on your catalog. This is where you will find your new extracted tables as the extraction runs successfully.
* **Folder**: a folder can be created inside the selected layer to group all tables being created from this new data source.
* **Table name**: we suggest a name, but feel free to customize it. You have the option to add a **prefix** to all tables at once and make this process faster!
* **Sync Type**: you can choose between INCREMENTAL and FULL\_TABLE.
  * Incremental: every time the extraction happens, we'll get only the new data, which is good if, for example, you want to keep every record ever fetched.
  * Full table: every time the extraction happens, we'll get the current state of the data, which is good if, for example, you don't want to have deleted data in your catalog.

Once you are done configuring, click **Next**.

### 4. Configure data source

Describe your data source for easy identification within your organization, not exceeding 140 characters.

To define your [Trigger](https://docs.nekt.com/runs/scheduling-and-triggers.md), consider how often you want data to be extracted from this source. This decision usually depends on how frequently you need the new table data updated (every day, once a week, or only at specific times).

Optionally, you can define some additional settings:

* Configure Delta Log Retention and determine for how long we should store old states of this table as it gets updated. Read more about this resource [here](https://docs.nekt.com/get-started/core-concepts/resource-control).
* Determine when to execute an **Additional [Full Sync](https://docs.nekt.com/get-started/core-concepts/types-of-sync#additional-full-sync)**. This will complement the incremental data extractions, ensuring that your data is completely synchronized with your source every once in a while.

Once you are ready, click **Next** to finalize the setup.

### 5. Check your new source

You can view your new source on the [Sources](https://app.nekt.ai/sources) page. If needed, manually trigger the source extraction by clicking on the arrow button. Once executed, your data will appear in your Catalog.

> [!WARNING]
>
> For you to be able to see it on your [Catalog](https://app.nekt.ai/catalog), you need at least one successful source run.

# Streams and Fields

## Available streams

| Stream | Slug | Description | Needs |
| - | - | - | - |
| Accounts | `accounts` | Advertiser accounts of your agency or corporation. | Report permission |
| Account Performance | `account_daily_report` | Daily metrics per account. | Report permission |
| Campaign Performance | `campaign_daily_report` | Daily metrics per campaign. | Report permission |
| Ad Set Performance | `ad_set_daily_report` | Daily metrics per ad set. | Report permission |
| Creative Performance | `creative_daily_report` | Daily metrics per ad creative. | Report permission |
| Video Performance | `video_daily_report` | Daily metrics per promoted video. | Report permission |
| Campaign Performance by Country | `campaign_country_daily_report` | Daily campaign metrics split by country. | Report permission |
| Campaign Performance by Operating System | `campaign_os_daily_report` | Daily campaign metrics split by iOS / Android. | Report permission |
| App Performance by Country | `app_country_daily_report` | *Not selected by default.* Daily metrics of your promoted apps by country. | Report permission + **App IDs** |
| Campaigns | `campaigns` | *Not selected by default.* Campaign settings: objective, bidding, budget, status. | Ads delivery read permission |
| Ad Sets | `ad_sets` | *Not selected by default.* Ad set settings: targeting, budget, schedule, bid. | Ads delivery read permission |
| Creatives | `creatives` | *Not selected by default.* Creative settings: video, texts, call to action, tracking URLs. | Ads delivery read permission |
| Agency Balance | `agency_balance` | *Not selected by default.* Agency wallet balances, one row per day. | Agency developer + **Agent ID** |
| Agency Monthly Consumption | `agency_monthly_consumption` | *Not selected by default.* Monthly agency bill by account and country. | Agency developer + **Agent ID** |
| Account Monthly Consumption | `account_monthly_consumption` | *Not selected by default.* Monthly bill of each account by country. | Agency developer + **Agent ID** |
| Agency Account Daily Spend | `agency_account_daily_spend` | *Not selected by default.* Daily spend of each account, by wallet type. | Agency developer + **Agent ID** |

**Report permission** (`ad_mapi_report`) is what a developer app gets when it is authorized in the Business Center, as described above. The **ads delivery read permission** (`ad_mapi_campaign_read`, `ad_mapi_unit_read`, `ad_mapi_creative_read`) is granted by Kwai only on request: e-mail [Kwaiapi@kuaishou.com](mailto:Kwaiapi@kuaishou.com), copying your Kwai sales contact, asking to extend your developer app, then repeat steps 5 and 6 and paste the new refresh token. Without it, those three tables are skipped and reported in the run log while the others sync normally. The performance tables already include campaign, ad set and creative names.

## Fields by stream

Every money column is in the currency of the account (see `currency`). Kwai sends money multiplied by 1,000,000; each money metric therefore has two columns: `cost` in currency units and `cost_micros` with the value as Kwai sent it.

> [accordion] Accounts
>
> * `account_id` - Kwai advertiser account ID
> * `account_name` - Account name
> * `legal_entity_name` - Legal entity that owns the account
> * `currency` - Account currency (USD, BRL...)
> * `owner_type` - `agent` or `corp`, the kind of ID used to list the account
> * `owner_id` - The Agent ID or Corp ID used to list the account
> * `extra_fields` - Other fields Kwai returned (JSON)

> [accordion] Performance tables (all daily reports)
>
> **Identification (all daily reports):**
>
> * `account_id`, `account_name`, `currency` - The advertiser account
> * `date` - Report day in the configured time zone (incremental key)
> * `time_zone` - Time zone used for the report day
>
> **Per table:**
>
> * Campaign Performance: `campaign_id`, `campaign_name`
> * Ad Set Performance: `campaign_id`, `campaign_name`, `ad_set_id`, `ad_set_name`
> * Creative Performance: `campaign_id`, `campaign_name`, `ad_set_id`, `ad_set_name`, `creative_id`, `creative_name`
> * Video Performance: `video_id`
> * Campaign Performance by Country: `campaign_id`, `campaign_name`, `country_code` (ISO numeric, 76 = Brazil; 0 = Kwai could not attribute a country)
> * Campaign Performance by Operating System: `campaign_id`, `campaign_name`, `os_id` (0 unknown, 1 iOS, 2 Android), `os_name`
> * App Performance by Country: `app_id`, `app_name`, `country_code`
>
> **Delivery:**
>
> * `cost` / `cost_micros` - Spend
> * `inc_tax_cost` / `inc_tax_cost_micros` - Spend including tax, when Kwai returns it
> * `exposure` - Impressions
> * `click` - Clicks
> * `ctr` - Click-through rate
> * `cpm`, `cpc`, `cpa` (and their `_micros`) - Cost per 1,000 impressions, per click and per conversion
> * `action`, `cvr` - Conversions and conversion rate
>
> **Video:**
>
> * `play3s`, `play5s`, `play_finished` - 3-second, 5-second and complete plays
> * `play3s_rate`, `play5s_rate`, `photo_thru_play_cnt`, `photo_thru_play_rate`
> * `photo25percent_play_cnt`, `photo50percent_play_cnt`, `photo75percent_play_cnt` - Plays reaching 25%, 50% and 75%
> * `photo_avg_play_time` - Average play time in seconds
> * `cost_performance_play3s`, `cost_performance_play5s`, `cost_photo_thru_play`, `cost_photo25percent_play` - Cost per 1,000 plays
>
> **Conversions (counted on the conversion day):**
>
> * `activation`, `activation_rate`, `cost_per_activation`
> * `app_launch`, `app_launch_rate`, `cost_per_app_launch`
> * `total_day_one_retention`, `day_one_retention_rate`, `cost_per_day_one_retention`
> * `key_in_app_action`, `unique_key_in_app_action`, `cost_key_in_app_action`
> * `page_view`, `page_view_rate`, `cost_per_page_view`
> * `registration`, `registration_rate`, `cost_per_registration`
> * `form_submit`, `form_submit_rate`, `cost_form_submit`
> * `add_to_cart`, `add_to_cart_rate`, `cost_per_add_to_cart`
> * `purchase`, `purchase_rate`, `cost_purchase`, `unique_purchase`, `cost_unique_purchase`
> * `first_deposit`, `credit_approval`, `loan_application`, `loan_credit`, `loan_disbursal` with their rates and costs
>
> **Other:**
>
> * `extra_metrics` - Metrics Kwai returned that do not have a column yet (JSON)

> [accordion] Campaigns
>
> * `account_id`, `campaign_id`, `campaign_name`
> * `ad_category` - 1 performance, 2 EyeMax, 3 boost, 4 brand guaranteed delivery
> * `marketing_type` - 1 app, 2 website
> * `campaign_type` - Objective: 1 awareness, 2 behavior, 3 conversion, 4 engagement, 5 and 6 catalog sales, 7 community, 9 ecommerce, 10 live
> * `delivery_strategy` - 1 bid cap, 2 target cost, 3 lowest cost, 4 cost cap
> * `budget_optimization` - Campaign budget optimization on (1) or off (0)
> * `open_status` - On (1) or off (2)
> * `status` - 1 active, 2 suspended, 3 deleted, 4 budget exceeded, 5 insufficient budget, 6 under review, 7 rejected, 8 completed
> * `day_budget` / `day_budget_micros` - Daily budget (0 = unlimited)
> * `budget_schedule_micros` - Budget per weekday, Monday to Sunday (JSON)
> * `data_generation_source` - 1 created in Ads Manager, 2 created through the API
> * `brand_order` - Brand order of EyeMax / First Sight campaigns (JSON)
> * `create_time`, `update_time`
> * `extra_fields` - Other fields Kwai returned (JSON)

> [accordion] Ad Sets
>
> * `account_id`, `campaign_id`, `ad_set_id`, `ad_set_name`
> * `ad_category`, `open_status`, `status`
> * `app_id`, `website_url`, `pixel_id` - What the ad set promotes and tracks
> * `placements` - 1 in-feed, 5 rewarded (JSON)
> * Targeting (JSON): `country_region_targeting`, `audience_ids`, `excluded_audience_ids`, `age_targeting`, `language_targeting`, `device_price_targeting`, `os_targeting`, `device_brand_targeting`, `content_interest_targeting`
> * `gender_targeting` - 1 male, 2 female, 0 or 3 unlimited
> * `day_budget` / `day_budget_micros`, `budget_schedule_micros`
> * `start_time`, `end_time`, `time_schedule` - Schedule and delivery hours per weekday
> * `optimization_goal` - Conversion target code (for example, 104 registration, 106 purchase)
> * `bid_type` - 1 CPM, 2 CPC, 3 CPV, 4 CPA, 8 CPT, 10 OCPM
> * `bid` / `bid_micros`, `roi_ratio`
> * `data_generation_source`, `create_time`, `update_time`, `extra_fields`

> [accordion] Creatives
>
> * `account_id`, `campaign_id`, `ad_set_id`, `creative_id`, `creative_name`
> * `ad_category`, `open_status`, `status`
> * `material_type` - 1 portrait, 2 landscape, 3 to 5 EyeMax, 6 native, 7 photo gallery, 8 live, 9 AIGC
> * `video_id` - Video used by the creative
> * `subtitle`, `description`, `call_to_action`, `deep_link`
> * `playable_id`, `interactive_material_ids`, `advertiser_name`, `avatar_id`
> * `impression_tracking_url`, `click_tracking_url`
> * `data_generation_source`, `create_time`, `update_time`, `extra_fields`

> [accordion] Agency tables
>
> **Agency Balance:** `agent_id`, `snapshot_date`, `snapshot_at`, and each wallet as currency units plus `_micros`: `total_balance`, `cash_balance`, `pre_balance` (top-up rebate), `after_balance` (delivery rebate), `contract_balance`, `direct_balance`, `credit_balance`.
>
> **Agency / Account Monthly Consumption:** `agent_id`, `account_id` (0 on agency totals), `country_code`, `charge_month` (first day of the month), and the spend by payment type: `total_cost`, `cash_cost`, `top_up_rebate_cost`, `delivery_rebate_cost`, `advertiser_rebate_cost`, `compensation_cost`, `credit_cost`.
>
> **Agency Account Daily Spend:** `agent_id`, `account_id`, `date`, `time_zone`, `total_cost`, `cash_cost`, `pre_rebate_amt`, `after_rebate_amt`, `credit_amt`, `impression`, `click`, `ctr`, `cpm`, `cpc`, `play3s`, `play5s`, `play_finished`, `conversion`.

## Good to know

* **Conversions count on the day they happen.** A conversion today from a click weeks ago is added to today's numbers, not to the day of the click, so no old day needs to be read again for it. The **Report Lookback Days** re-read the recent days because some events reach Kwai late (delayed app or pixel postbacks). Increase it if your app or pixel sends events with long delays.
* **New accounts take about 6 hours** to reach the Marketing API. Until then, a run that cannot read an account says so in the run log and reads it again on the next run.
* **Daily quota.** Kwai limits the number of API calls per day. If the quota runs out, the run stops with a clear message. The performance tables keep, for each account, the last complete period they read (up to 30 days at a time), so the next run continues from there instead of starting over; a long history may take a few days to load. Select only the tables you use to save calls.
* **Deleted campaigns, ad sets and creatives** disappear from the settings tables (Kwai lists only entities that are not deleted), but their history stays in the performance tables.
* **Agency Balance** only has the balance of the day it is read: Kwai does not provide past balances. Any full sync of this table, manual or a scheduled **Additional Full Sync**, replaces the history with today's row. The Additional Full Sync is a setting of the source: do not schedule it for this source if you want to keep this table's history.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.