# Core concepts (/concepts)



A few words show up everywhere in UnifAPI. Learn them once and the rest of the docs read faster.

## Provider [#provider]

The upstream service an API exposes data from — TikTok today, and (roadmap) Instagram, YouTube, Google, etc. Every provider has a top-level path prefix.

```
https://api.unifapi.com/tiktok/...
```

## Operation [#operation]

A single callable endpoint inside a provider — for example `GET /tiktok/videos/{id}`. Every operation has its own page in the [API reference](/api).

## Canonical schemas [#canonical-schemas]

Every operation that returns the same kind of resource — a Video, a User, a Comment — uses the same canonical schema. So `GET /tiktok/videos/{id}` and `GET /tiktok/users/{id}/videos` both return `Video` objects with identical field names and types.

The canonical shapes live in `components.schemas` of the [OpenAPI spec](https://api.unifapi.com/openapi.json) and include: `Video`, `Author`, `Music`, `MusicDetail`, `Comment`, `User`, `Hashtag`, `LiveRoom`.

## Identifiers [#identifiers]

IDs are **opaque strings**. They look like long numbers, but treat them as strings to preserve precision (some are > 2^53).

* TikTok user id (sec\_uid) is a long base64 token, e.g. `MS4wLjABAAAA...`.
* TikTok video / music / hashtag / live ids are numeric-looking strings.

Resolve a username to a sec\_uid with `/tiktok/users/resolve?username=jennmelon`. Resolve a share URL to a video with `/tiktok/videos/resolve?url=...`.

## List envelope and pagination [#list-envelope-and-pagination]

Every list endpoint returns the same envelope:

```json
{
  "items": [/* ... */],
  "has_more": true,
  "next_cursor": "1711494099000"
}
```

* `items` — the resource list.
* `has_more` — `true` when at least one more page exists.
* `next_cursor` — **opaque string** to pass back as `?cursor=` for the next page. `null` when `has_more` is `false`.

The `limit` query parameter is capped at 50.

Cursors are deliberately opaque: some upstreams use integer offsets, others use timestamps, others use page tokens. UnifAPI hides the variation. Don't try to parse `next_cursor`.

## Error envelope [#error-envelope]

All errors share a single nested envelope:

```json
{ "error": { "type": "...", "message": "...", "request_id": "...", "issues": [/* validation only */] } }
```

`error.type` is a closed vocabulary (`validation_error`, `not_found`, `unauthorized`, ...). See [Errors](/errors).

## Workspace [#workspace]

The billing and access boundary. API keys, usage, and invoices all live at the workspace level. Invite teammates from the dashboard — they share the same keys and the same usage counter.
