> For the complete documentation index, see [llms.txt](https://docs.rad.live/rad/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.rad.live/rad/rad-tv-developer-api/best-practices.md).

# Best Practices

Short recommendations for integrating with the Rad TV API.

## Use DIDs everywhere

Use **DIDs** as the canonical ID for channels and content (e.g. `did:rad.live:channel/<uuid>`, `did:rad.live:content/feature/<id>`). Do not mix raw content-metadata or 12core IDs with DIDs in client flows.

## Channel catalog: use features, not content

Channels do **not** have a legacy `content` field. Use:

* `channel.features(limit, start)`
* `channel.series(limit, start)`
* `channel.episodes(limit, start)`
* `channel.streams(limit, start)`
* `channel.seasons(limit, start)`
* `channel.miniseries(limit, start)`

Catalog types (Feature, Episode, Stream, Serie, Season, Miniseries) implement Likeable and Commentable (id, likes, commentCount, comments).

## Rely on nullability in the schema

The schema uses `!` for non-null fields. Use this when writing clients:

* **Content:** `metadata`, `assets`, `likes`, and `commentCount` are never null. `assets` may have empty `videos`/`images` before upload. `transcodeJob` and `outputAssets` are null when not processing or not available.
* **Single-entity queries:** `channel(id)`, `feature(id)`, `stream(id)`, etc. return **null** when the entity is not found or not accessible. Check for null before using the result.

Generated TypeScript types (from `npm run codegen`) reflect the schema.

## Handle both data and errors

* **GraphQL:** Responses are `{ data?, errors? }`. Always check `response.errors`; the HTTP status may still be 200 when there are field errors. Use `response.data` for the result.
* **REST/Internal:** Success uses `{ data: <payload> }`; errors use `{ errors: [ { message, code? } ] }`.

## Use API keys for automation

For MCP, scripts, or long-lived access, use an **API key** (from `POST /internal/v0/generate-api-key`) instead of a user JWT. JWTs are for user sessions; API keys are for programmatic and IDE integration.

## Discover the schema

Use **introspection** against `POST /graphql` or the Altair playground at `/altair` (in development) to explore the full schema. This helps avoid trial-and-error when building queries.

## Pagination

List queries use `limit` and `start` (offset). There is no cursor-based pagination or total count in the schema. Implement "next page" by incrementing `start` by `limit` until you get fewer results than `limit` or an empty list.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.rad.live/rad/rad-tv-developer-api/best-practices.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
