# Tryr developer docs: REST API, MCP server and CLI

> Tryr turns a product page link into on-model product photos and short product films. This page is for developers and AI agents that use Tryr through the REST API (`/agent/v1`), the MCP server (`/mcp`) or the CLI. Tryr is an Agentized.io product.

- OpenAPI 3.1 document: [https://tryr.app/agent/v1/openapi.json](https://tryr.app/agent/v1/openapi.json)
- MCP endpoint (Streamable HTTP): `https://tryr.app/mcp`
- Client setup snippets for MCP clients, REST and CLI: [https://tryr.app/agents/en](https://tryr.app/agents/en)
- LLM summary: [https://tryr.app/llms.txt](https://tryr.app/llms.txt) · API catalog (RFC 9727): [https://tryr.app/.well-known/api-catalog](https://tryr.app/.well-known/api-catalog)
- This page as Markdown: [https://tryr.app/developers.md](https://tryr.app/developers.md) (or request it with `Accept: text/markdown`)

## Authentication

Every call uses the user's personal API key as a bearer token: `Authorization: Bearer tryr_sk_...`.

1. Sign in on tryr.app and open the panel. Under **Agent access**, select **Create API key**. The key is shown only once.
2. The key belongs to the account: calls spend that account's credits. Keep it private; if it leaks, revoke it in the same section.
3. Keys work only on accounts that have made a purchase (a plan or a credit top-up).

A missing, invalid or revoked key returns `401 auth_required` with `WWW-Authenticate: Bearer realm="tryr"`. A key on an account without a purchase returns `403 purchase_required`.

There is no separate sandbox. Reading the account, listing plans, starting a shoot (reading the product page and getting the questions) and building a film plan and quote are free, so an integration can be tested end to end before anything is charged.

## Quickstart

1. Start a shoot from a product page. Put a concrete brief in `notes` (setting, light, framing, mood, what to avoid; at most 300 characters).

```
curl -X POST https://tryr.app/agent/v1/shoots \
  -H "Authorization: Bearer tryr_sk_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6f1c2b7e" \
  -d '{"url":"https://store.example/product","lang":"en"}'
```

The response is `202` with `shoot_id`, `status` and `next`. Every response carries a `next` field that names the next step.

2. Poll the status. `wait_seconds` (up to 50) holds the request until something changes, so there is no need for fast polling.

```
curl "https://tryr.app/agent/v1/shoots/SHOOT_ID?wait_seconds=50" \
  -H "Authorization: Bearer tryr_sk_..."
```

3. When `status` is `awaiting`, ask the user the `questions` and tell them the cost, then send the answers. An empty `answers` object uses the defaults. This starts generation and charges credits: every generated image, including the first two previews, costs 2 credits at 1K or 2K and 5 credits at 4K.

```
curl -X POST https://tryr.app/agent/v1/shoots/SHOOT_ID/answers \
  -H "Authorization: Bearer tryr_sk_..." \
  -H "Content-Type: application/json" \
  -d '{"answers":{},"scene_count":4,"resolution":"1K","aspect":"3:4"}'
```

4. Show frames with the free 720 px preview (`GET /agent/v1/shoots/{id}/frames/{n}/preview`; the `preview_url` in the status is signed and works without the key for 15 minutes). Download full resolution only when the user wants it: `GET /agent/v1/shoots/{id}/frames/{n}?size=1k|2k|4k`. A download costs only the size difference over what the frame already paid, and the same frame and size is never charged twice.
5. When `scene_count` is above 2, `POST /agent/v1/shoots/{id}/approve` generates the remaining planned scenes (charged per scene; ask the user first).
6. A film is two steps. `POST /agent/v1/shoots/{id}/films` returns a plan and a credit quote and charges nothing. `POST /agent/v1/shoots/{id}/films/{film}/approve` charges the quoted credits once, only after the user approves the price. Then poll `GET /agent/v1/shoots/{id}/films/{film}?wait_seconds=50` and download with `GET /agent/v1/shoots/{id}/films/{film}/download`.

Out of credits (`402 plan_gerekli` or `402 insufficient_credits`): list plans with `GET /agent/v1/plans`, let the user choose, create a checkout link with `POST /agent/v1/checkout`, and read the balance with `GET /agent/v1/me` after they pay. The agent never charges a card; the user pays on the checkout page.

## Endpoints

| Method and path | Purpose | Cost |
|---|---|---|
| `GET /agent/v1/me` | Account, credit balance and current prices | Free |
| `GET /agent/v1/plans` | Credit plans, billing terms and USD prices | Free |
| `POST /agent/v1/checkout` | Checkout link for a plan (`package`, `term`) | Free; the user pays on the link |
| `GET /agent/v1/shoots` | Recent shoots (`limit` up to 100) | Free |
| `POST /agent/v1/shoots` | Start a shoot from a product URL | Free |
| `GET /agent/v1/shoots/{id}` | Status, questions, frames and `next` (`wait_seconds`) | Free |
| `POST /agent/v1/shoots/{id}/answers` | Answer the questions and start generation | 2 credits per image (5 at 4K) |
| `POST /agent/v1/shoots/{id}/approve` | Generate the remaining planned scenes | 2 credits per scene (5 at 4K) |
| `GET /agent/v1/shoots/{id}/frames/{n}/preview` | 720 px preview | Free |
| `GET /agent/v1/shoots/{id}/frames/{n}` | Full resolution frame (`size=1k`, `2k`, `4k`) | Size difference, once |
| `POST /agent/v1/shoots/{id}/films` | Film plan and credit quote | Free |
| `POST /agent/v1/shoots/{id}/films/{film}/approve` | Approve the quote and start the film | Quoted credits, once |
| `GET /agent/v1/shoots/{id}/films/{film}` | Film status and progress (`wait_seconds`) | Free |
| `GET /agent/v1/shoots/{id}/films/{film}/download` | Completed MP4 | Free |

Request and response schemas for every operation are in the [OpenAPI document](https://tryr.app/agent/v1/openapi.json).

## MCP server

The MCP server lives at `https://tryr.app/mcp` (Streamable HTTP, stateless: `POST` only) and takes the same bearer key in the `Authorization` header. Tools:

- `tryr_hesap`: account, credits and prices. `tryr_paketler`: credit plans. `tryr_kredi_al`: checkout link (does not charge).
- `tryr_cekimler`: recent shoots. `tryr_cekim_baslat`: start a shoot from a product URL. `tryr_cekim_durumu`: status, questions and frames (`wait_seconds`).
- `tryr_cevapla`: answer the questions and start generation. `tryr_onayla`: generate the remaining scenes.
- `tryr_kare_onizle`: free preview. `tryr_kare_indir`: full resolution frame (charges once per frame and size).
- `tryr_film_baslat` → `tryr_film_onayla` → `tryr_film_durumu` → `tryr_film_indir`: film plan and quote, approval, status, download link.

Setup snippets for individual MCP clients are on [https://tryr.app/agents/en](https://tryr.app/agents/en).

## Errors

Every error from `/agent/v1` is an RFC 9457 problem object served as `application/problem+json`. Unknown paths under `/agent`, `/api` and `/v1` also return a JSON problem object instead of an HTML page.

```
HTTP/1.1 401 Unauthorized
Content-Type: application/problem+json
WWW-Authenticate: Bearer realm="tryr"

{
  "type": "https://tryr.app/developers#errors",
  "title": "Unauthorized",
  "status": 401,
  "detail": "API anahtari eksik, gecersiz ya da iptal edilmis.",
  "instance": "/agent/v1/me",
  "error": "auth_required",
  "message": "API anahtari eksik, gecersiz ya da iptal edilmis.",
  "hint": "Send a personal API key as `Authorization: Bearer tryr_sk_...`; create one in the Tryr panel under Agent access.",
  "docs": "https://tryr.app/developers"
}
```

- `error` is the stable machine-readable code. Branch on it, not on the text.
- `detail` and `message` explain the error (Turkish today); `hint` is the next step in English.
- Credit errors add `required` and `available` when they are known.

| `error` | Status | Meaning and next step |
|---|---|---|
| `auth_required` | 401 | Key missing, invalid or revoked. Send `Authorization: Bearer tryr_sk_...`. |
| `purchase_required` | 403 | Keys work only on accounts with a purchase. Ask the user to buy a plan or a top-up. |
| `admin_required` | 403 | On a team account only an admin can buy credits. |
| `not_found` | 404 | The shoot or film does not exist or belongs to another account. |
| `route_not_found` | 404 | No such method and path. Check the OpenAPI document. |
| `invalid_url`, `url_required` | 400 | Send the full address of a product page in `url`. |
| `invalid_json` | 400 | The body is not valid JSON. |
| `frames_required` | 400 | Pick frames whose status is `completed`. |
| `size_unavailable` | 400 | That size was not produced for this shoot; ask for a smaller one. |
| `invalid_package`, `email_required` | 400 | Use a `package` from `GET /agent/v1/plans`; the account needs a verified email. |
| `plan_gerekli`, `insufficient_credits` | 402 | Not enough credits. List plans and offer a checkout link. |
| `not_awaiting`, `not_ready`, `busy` | 409 | The shoot or film is in another state. Read the status and follow `next`. |
| `plan_yok`, `plan_onayi_guncel_degil` | 400 or 409 | The film plan is missing or changed. Read the film again and approve the current plan and price. |
| `idempotency_key_reused` | 422 | The `Idempotency-Key` was used for a different request. Use a new key. |
| `price_not_configured`, `stripe_not_configured` | 503 | Checkout is unavailable right now. Retry later. |
| `internal_error`, `upstream_error` | 5xx | Retry later; if it keeps failing, write to support@agentized.io. |

## Idempotency

Send an `Idempotency-Key` header (up to 200 characters) on `POST` requests. Repeating the same key on the same path returns the first response with `Idempotent-Replayed: true` and does not start a second shoot, film or checkout. Using the key on a different path returns `422 idempotency_key_reused`. Responses with a 5xx status are not stored, so a retry after a server error runs again. Frame downloads are idempotent by design: the same frame and size is never charged twice.

## Rate limits

The agent API has no per-key request quota today, so responses carry no `RateLimit` headers. Usage is bounded by the account's credits. Status calls accept `wait_seconds` (up to 50) so an agent can wait for a change instead of polling in a tight loop. If a request limit is introduced, it will be announced on this page first, responses will carry the IETF `RateLimit-Policy` and `RateLimit` headers, and a `429` will include `Retry-After`.

## Versioning and deprecation

- The REST API is versioned in the path: `/agent/v1`. The OpenAPI document states the current version in `info.version`.
- Within `v1`, changes are additive: new endpoints, new optional fields, new error codes. Clients should ignore fields they do not know.
- A breaking change ships under a new path (`/agent/v2`); `v1` keeps working until its sunset date has been announced.
- Before an operation is removed it is marked `deprecated: true` in the OpenAPI document, and its responses carry a `Deprecation` header (RFC 9745), a `Sunset` header with the removal date (RFC 8594) and a `Link` to this section. The change is also listed here.
- Nothing is deprecated today.

## CLI

The `tryr` command-line client has not been published to npm yet; until then, use MCP or the REST API. Its commands mirror the API, support `--json` for machine-readable output and read the key from the `TRYR_API_KEY` environment variable:

```
tryr film start <shoot-id> --duration 15 --tier 720p
tryr film approve <shoot-id> <film-id>
tryr film status <shoot-id> <film-id> --wait
tryr film download <shoot-id> <film-id>
```

## Pricing

Prices are in credits; `GET /agent/v1/me` returns the current prices for the account. On a monthly plan 1 credit is about $0.05. Plans start at $49 a month (Starter, 1,000 credits) and top-ups at $10 ($1 = 20 credits). Full pricing: [https://tryr.app/#pricing](https://tryr.app/#pricing). Plans are subscriptions that renew until cancelled; the terms are in the [Terms of Service](https://tryr.app/terms).

## Support

- Questions about the API, bulk use and integrations: info@agentized.io
- Support: support@agentized.io
- [About Tryr](https://tryr.app/about) · [Contact](https://tryr.app/contact) · [Terms of Service](https://tryr.app/terms) · [Privacy Policy](https://tryr.app/privacy)
