# ANY /v1/raw/{upstream path}

Verbatim pass-through to the upstream provider. Anything TikData has no custom endpoint for is reachable here, so adopting the router never blocks you on us adding something first. The caller's key selects the project for attribution; the real upstream key never leaves the server.

## Request

Append the upstream path after `/v1/raw/`. Query parameters and the request body are forwarded exactly as given. `GET`, `POST`, `PUT` and `DELETE` are supported.

```bash
curl "https://tikdata.io/v1/raw/api/v1/tiktok/app/v3/fetch_one_video?aweme_id=7680721699171601694" \
  -H "Authorization: Bearer thr_live_xxx"
```

```bash
curl -X POST "https://tikdata.io/v1/raw/api/v1/tiktok/app/v3/fetch_multi_video" \
  -H "Authorization: Bearer thr_live_xxx" \
  -H "content-type: application/json" \
  -d '["7680721699171601694","7680396811227401486"]'
```

## Response

The upstream response, unchanged: same status code, same body, same `content-type`. Two headers are added:

| header | value |
|---|---|
| `cache-control` | `no-store` |
| `x-router-project` | the project this call was attributed to |

Because the body is untouched, the upstream provider's own envelope applies — including its habit of answering HTTP 200 with the post object omitted for deleted content. `/v1/raw` does **not** apply the 404 normalization that `/v1/post` does; if you need that, use the typed endpoints.

## Migrating an existing consumer

Most consumers can move with two configuration changes and no code:

```
before:  BASE_URL = https://api-node-enterprise.tikhub.io
         API_KEY  = <the shared account key>

after:   BASE_URL = https://tikdata.io/v1/raw
         API_KEY  = thr_live_<this consumer's own key>
```

Existing call sites keep working; every call is now attributed to the consumer's project and the shared key is out of its environment.

## Billing and attribution

Calls under `/api/v1/tikhub/user/` (account info, price catalogue, usage meter) are free upstream and are not counted. Everything else under `/api/v1/` is counted against the key's project when the upstream answers 2xx. Errors are free, as they are upstream.

## Scopes

A key created with `scopes` may only reach paths starting with one of them. Outside that: **403** `{"error":"key is not scoped for this path","hint":"allowed: /api/v1/tiktok/, ..."}`.

## Errors

| status | body |
|---|---|
| 401 / 403 | see [authentication](/docs/authentication.md) |
| 502 | `{"error":"upstream unreachable"}` — timeout or network failure; the upstream's own error statuses pass through as-is |

## Rate limiting

Outbound calls are held under the plan limit (100 req/s on the enterprise node) by a sliding window. A caller cannot collect upstream 429s by going too fast; requests queue briefly instead. Note the limiter is per warm instance, not account-wide — see the README for why that matters at very high concurrency.
