Agent API
Programmatic access for AI agents with credits-based pricing.
Start here first
If you want the shortest zero-to-first-call path, read Agent Quickstart first.
If you are still deciding whether Rynjer is the right fit, start from For Agents.
If you need help deciding whether Nano Banana 2 should be the first model, use the Model Routing Guide.
Quick start
Fast path for most builders
- Read Agent Quickstart
- Check model fit with Model Routing Guide
- Estimate with
POST /v1/credits/estimate - Call
POST /v1/generate - Poll
GET /v1/generate/{requestId}if needed
Minimal call (example)
POST /v1/generate
{
"model": "nano-banana-pro",
"prompt": "Studio product shot of a matte black smart speaker on a neutral background, soft commercial lighting, premium ad look",
"request_id": "uuid"
}Machine-first examples
This section is for builders who want copy-paste examples instead of product-level explanation.
Example 1: inspect the model catalog
curl -s https://rynjer.com/v1/models/list \
-H "Authorization: Bearer $RYNJER_ACCESS_TOKEN"Use this when the agent should inspect the current catalog instead of hardcoding model assumptions.
Example 2: estimate credits before generation
curl -s https://rynjer.com/v1/credits/estimate \
-H "Authorization: Bearer $RYNJER_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"product": "image",
"model": "nano-banana-pro",
"units": {
"count": 1,
"resolution": "1K"
}
}'Example 3: submit a generation request
curl -s https://rynjer.com/v1/generate \
-H "Authorization: Bearer $RYNJER_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"request_id": "demo-uuid-001",
"model": "nano-banana-pro",
"prompt": "Studio product shot of a matte black smart speaker on a neutral background, soft commercial lighting, premium ad look"
}'Example 4: poll the same request
curl -s https://rynjer.com/v1/generate/demo-uuid-001 \
-H "Authorization: Bearer $RYNJER_ACCESS_TOKEN"Authentication
App-level usage
- API Key:
Authorization: Bearer <api_key> - Moltbook:
POST /auth/moltbook/exchange→access_token(15 min)
Agent identity flow
If you need the more explicit autonomous-agent path, the current flow is:
POST /api/v1/agents/register- Bind the returned
registration_codeto a user account POST /api/v1/agents/keys/createPOST /api/v1/agents/auth/token- Use the resulting bearer token on
/v1/*
This keeps long-lived key issuance and short-lived access separate.
Token flow example
The autonomous path is more verbose, but it is the right fit when the agent needs its own identity lifecycle.
Step 1: register the agent identity
curl -s https://rynjer.com/api/v1/agents/register \
-H "Content-Type: application/json" \
-d '{
"public_key": "<ed25519_public_key_hex>",
"agent_name": "Demo Agent",
"agent_version": "0.1.0",
"timestamp": 1742291400,
"nonce": "random-nonce",
"signature": "<signature_hex>"
}'Expected response shape:
{
"success": true,
"data": {
"agent_id": "...",
"registration_code": "...",
"expires_at": "..."
}
}Then bind registration_code to the owner account outside the API flow.
Step 2: create a long-lived API key
curl -s https://rynjer.com/api/v1/agents/keys/create \
-H "Content-Type: application/json" \
-d '{
"agent_id": "<agent_id>",
"registration_code": "<registration_code>",
"key_name": "demo-key",
"scopes": ["image"],
"expires_in_days": 90,
"timestamp": 1742291460,
"nonce": "random-nonce-2",
"signature": "<signature_hex>"
}'Expected response shape:
{
"success": true,
"data": {
"key_id": "...",
"api_key": "ryn_agent_v1_...",
"scopes": ["image"],
"expires_at": "..."
}
}Step 3: exchange API key for short-lived access token
curl -s https://rynjer.com/api/v1/agents/auth/token \
-H "Authorization: Bearer $RYNJER_AGENT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "<agent_id>",
"scopes": ["image"],
"timestamp": 1742291520,
"nonce": "random-nonce-3",
"signature": "<signature_hex>"
}'Expected response shape:
{
"code": 0,
"message": "ok",
"data": {
"access_token": "...",
"token_type": "Bearer",
"expires_in": 900,
"refresh_token": "...",
"agent_id": "...",
"account_id": "...",
"scopes": ["image"]
}
}Step 4: refresh when needed
curl -s https://rynjer.com/api/v1/agents/auth/refresh \
-H "Content-Type: application/json" \
-d '{
"refresh_token": "$RYNJER_REFRESH_TOKEN"
}'Request normalization details
POST /v1/generate accepts a few machine-friendly shortcuts:
- top-level
count,resolution,duration, andaspect_ratioare normalized intounits image_urlsis normalized intoinput_image_urlsproductcan be omitted when the model makes the product obvious
Example using top-level shortcuts:
curl -s https://rynjer.com/v1/generate \
-H "Authorization: Bearer $RYNJER_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"request_id": "demo-uuid-002",
"model": "qwen/text-to-image",
"prompt": "Minimal ecommerce hero image for a skincare bottle, front-facing, soft shadow, high-end brand aesthetic",
"count": 1,
"resolution": "1K",
"aspect_ratio": "1:1"
}'Balance, estimate, and model discovery
GET /v1/credits/balancePOST /v1/credits/estimateGET /v1/models/list
Estimate request
{
"product": "image",
"model": "nano-banana-pro",
"units": { "count": 1, "resolution": "1K" },
"price_version": "2026-02-02-v1"
}Model list response shape
GET /v1/models/list returns:
currencyprice_versionmodels
Use it when the agent needs to inspect the current catalog instead of assuming one fixed model list.
Generate (v1)
Request fields
request_id(required)model(required)prompt(required for text-to-*)product(optional: image/video/music; auto-detected if omitted)units:{ count, resolution, duration, aspect_ratio }input_image_urls(for image-to-image / image-to-video)price_version(optional)- top-level shortcuts like
count,resolution,duration, andaspect_ratioare normalized intounits image_urlsis normalized intoinput_image_urlswhen needed
Idempotency: reusing the same request_id will not double-charge.
Response (JSON-only)
{
"code": 0,
"message": "ok",
"data": {
"task_id": "...",
"provider_task_id": "...",
"status": "pending",
"usage_event_id": "..."
}
}Polling
If the task remains pending, poll:
GET /v1/generate/{requestId}Pricing (credits)
All pricing is credits. For images, count multiplies the cost (1/2/4/8).
Image models (per image)
| Model | Credits | Notes |
|---|---|---|
google/nano-banana | 8 | fast draft |
nano-banana-pro | 20 | 4K = 40 |
gpt4o_image | 10 | |
qwen/text-to-image | 15 | |
qwen/image-to-image | 15 | |
xai/grok-imagine-image | 20 | |
xai/grok-imagine-image/edit | 20 | |
z-image | 20 |
Video models
| Model | Credits | Notes |
|---|---|---|
sora-2 | 10 | 720p baseline |
sora-2-pro | 330 | |
veo3_fast | 50 | |
veo3 | 280 | 1080p = 350 |
doubao-seedance-1.0-pro-fast | 40 | |
wan-2.6 | 20 | 1080p = 300 |
fal-ai/ltx-2/image-to-video | 50 | |
xai/grok-imagine-video/text-to-video | 10 |
Notes:
- 1080p may apply ~1.8x on some models (use
/v1/credits/estimatefor exact pricing). - image-to-video can apply a 1.5x multiplier for some models.
Music models
| Model | Credits |
|---|---|
V5 | 35 |
V4_5PLUS | 30 |
V4_5 | 25 |
V4 | 20 |
Autonomous agent endpoints
These endpoints matter when the agent manages its own identity lifecycle:
POST /api/v1/agents/registerPOST /api/v1/agents/keys/createPOST /api/v1/agents/auth/tokenPOST /api/v1/agents/auth/refreshPOST /api/v1/agents/keys/listPOST /api/v1/agents/keys/revoke
Use this path if you want agent registration, owner binding, scoped keys, and short-lived access tokens.
Errors (JSON)
Common errors:
{
"code": 0,
"message": "ok",
"data": {
"error": "insufficient_credits",
"required": 50,
"available": 10,
"suggestion": "Use a cheaper model or ask the owner to top up."
}
}Machine-readable docs
- OpenAPI:
/agent/openapi.json - llms.txt:
/llms.txtand/agent/llms.txt