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

# TikTok

> What a Nephia Watch on TikTok captures, and what arrives in each event.

<Note>
  TikTok is **powered by a provider**. Every other Source here is read by Nephia directly; TikTok's public APIs do not serve third-party listening at all — the Research API forbids commercial use, the Display API returns only the authenticating creator's own videos — and TikTok's web surfaces cannot be paginated reliably from a server. So a metered provider answers these Watches, which is why they cost more and poll less often than the rest. On Nephia's hosted API it is configured; if you self-host, set `SCRAPEBADGER_API_KEY`. `GET /account` reports which Sources a deployment offers in `capabilities.liveSources`.
</Note>

## The item

A TikTok Watch emits a **TiktokVideo**. The entity and the event are prefixed — `tiktok_video.created`, `tiktokVideo` — because YouTube already owns `video.created` and the bare `video` key. A receiver can tell the two platforms apart without reading `watch.source`.

A **photo slideshow** is a TiktokVideo too. TikTok models it as the same kind of post, it comes back in the same search results, and splitting it out would mean a keyword Watch silently dropping half its matches. `isSlideshow` carries the difference.

`caption` is the whole text of a TikTok — there is no title.

`playCount` is views, and it is what the Feed and Insights read as **Reach**.

**No playback URL.** TikTok's `play_addr` and `download_addr` are signed and expire within hours, so an event that carried one would hand you a link that is dead by the time your job reads it. `url` is the durable way back to the post. `coverUrl` is a still image and may go stale the same way — treat a load failure as expected.

`musicTitle` and `musicAuthor` are frequently `null`, and that is upstream: the 2026 rights dispute leaves music metadata empty on a large share of posts.

## Coverage

A Watch takes **exactly one** of `query` or `user`. Both, or neither, is a `400` — they are two different upstream calls at two different costs, so picking one for you would be a bill you did not ask for.

| Criterion | Values                        | Default      |
| --------- | ----------------------------- | ------------ |
| `query`   | search text                   | one of these |
| `user`    | a `@handle`, or a profile URL | one of these |
| `region`  | ISO 3166-1 alpha-2            | `US`         |

`region` **routes** the request through a signer and proxy for that locale. It is not a filter on where a video was made: the same query genuinely answers differently per region, which is the point. Supported regions are US, GB, CA, AU, IE, DE, FR, ES, IT, NL, PL, PT, SE, BR, MX, AR, JP, KR, ID, TH, VN, PH, MY, SG, TR, SA, AE and RU.

### What a keyword Watch actually matches

**The caption, and only the caption.** TikTok's own search also reads on-screen text and speech, but the API returns neither, so a video that says your brand out loud and never types it will not be found. This is the Source's real limit and it is worth knowing before you rely on it.

**TikTok search has no "no results".** A term that matches nothing comes back with fuzzy, unrelated videos rather than an empty page. A probe on 2026-09-01 asked for a term nobody has ever posted and got eleven unrelated videos back.

That makes `match` worth setting on this Source, where on most it is a refinement. The default, `platform`, passes the provider's results through as they are — which here means TikTok's own idea of a near-match, including videos that merely resemble your term or come from a similarly-named creator. Set `match` to `word` and Nephia holds every result to your term itself and drops the rest, so a quiet Watch is genuinely quiet rather than a stream of strangers.

It also means `terms` is not supported here and one term is the maximum: the upstream takes a single query string and does not honour a boolean join.

A creator Watch has no term to match against, so it reports **everything** that handle posts.

Interval: **3600–86400** seconds. Cap: **10** active Watches per Account. Each tick costs **40 credits**.

The floor is not politeness, it is cost. The provider has no conditional request and no "since" parameter, so **every tick is paid for upstream whether or not anything is new** — including a tick that finds nothing. An hour is the interval at which that stays sustainable, and it is why your plan's one-minute chip does not apply to this Source: the effective minimum is always the higher of your plan's floor and the Source's.

## What an event carries

The first tick establishes a silent baseline and emits nothing. Later ticks emit `tiktok_video.created`. `webhook_url` is optional — without it the Watch still records every match, readable through `GET /v1/tiktok/watches/{id}/events`. See [Webhooks](/webhooks).

```bash theme={null}
curl -X POST https://api.nephia.cc/v1/tiktok/watches \
  -H "x-api-key: $NEPHIA_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "query": "nephia",
    "region": "US",
    "refresh_interval_seconds": 3600,
    "webhook_url": "https://example.com/hooks/nephia"
  }'
```

Watching a creator instead:

```bash theme={null}
curl -X POST https://api.nephia.cc/v1/tiktok/watches \
  -H "x-api-key: $NEPHIA_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "user": "@duolingo",
    "refresh_interval_seconds": 3600
  }'
```

A common shape — a brand mention that actually travelled — is a Watch plus one rule: `tiktokVideo.playCount > 10000`.

## Errors

A temporary provider failure is **503** and is not charged; the Watch reports it in its activity, readable through `GET /v1/tiktok/watches/{id}/activity`. A throttle answers **429** and is not charged either.

A handle that does not exist is **not** an error. The upstream answers it with an empty page, so a Watch on a typo'd creator polls forever and never emits — which is why the handle's shape is validated when the Watch is created. Check the spelling against the profile URL if a creator Watch stays silent.

A deployment with no provider key answers **503** on these routes and omits `tiktok` from `capabilities.liveSources`.
