Introduction
The RunKey.ai API provides RESTful access to on-demand GPU compute. Save your compute template once, then invoke it through standard HTTP requests — the platform allocates a GPU per task and releases it the moment execution finishes.
Template invocations are asynchronous. When you submit a run request, the API returns a task_id immediately. Use this ID to poll for status or configure a webhook for completion notifications.
# RunKey.ai API - Quick Example
# 1. Run a template
curl -X POST "https://api.runkey.ai/v1/run" \
-H "Authorization: Bearer rk_live_xxxxx" \
-H "Content-Type: application/json" \
-d '{
"template_id": "tpl_abc123",
"input": {
"image_url": "https://example.com/photo.jpg",
"style": "portrait"
}
}'
# Response:
# {
# "code": 0,
# "data": {
# "task_id": "task_xyz789",
# "status": "queued"
# }
# }
# 2. Poll task status
curl "https://api.runkey.ai/v1/tasks/task_xyz789" \
-H "Authorization: Bearer rk_live_xxxxx"Authentication
All API requests require authentication via an API key in the Authorization header.
Authorization: Bearer rk_live_xxxxxAPI keys can be created and managed in the API Keys section of your console.
# Include your API key in the Authorization header
curl "https://api.runkey.ai/v1/account" \
-H "Authorization: Bearer rk_live_xxxxx"
# Response:
# {
# "code": 0,
# "data": {
# "email": "user@example.com",
# "balance": 5000,
# "plan": "pro"
# }
# }Base URL
All API requests use the following base URL:
https://api.runkey.ai/v1Available Endpoints
POST/runGET/tasks/{task_id}GET/account
# Production API
https://api.runkey.ai/v1
# All endpoints are relative to this base URL
# Example full URL:
https://api.runkey.ai/v1/run
https://api.runkey.ai/v1/tasks/{task_id}
https://api.runkey.ai/v1/accountInvoke Template
Invoke a saved template to start a new task. The request returns immediately with a task_id that you can use to track progress — a GPU is allocated per task and released the moment execution finishes.
POST/runRequest Body
template_id | string | Required. The template ID to invoke. |
input | object | Required. Template input parameters. |
webhook_url | string | Optional. URL for completion callback. |
# POST /run
# Start a new template execution
curl -X POST "https://api.runkey.ai/v1/run" \
-H "Authorization: Bearer rk_live_xxxxx" \
-H "Content-Type: application/json" \
-d '{
"template_id": "tpl_portrait_fix",
"input": {
"image_url": "https://example.com/photo.jpg",
"enhancement": "high",
"output_format": "png"
},
"webhook_url": "https://your-server.com/callback"
}'
# Response (202 Accepted):
# {
# "code": 0,
# "data": {
# "task_id": "task_8f3a2b",
# "status": "queued",
# "created_at": "2026-03-23T00:00:00Z"
# }
# }Get Task Status
Query the current status and result of a task.
GET/tasks/{task_id}Task Status Values
- ●queued - Waiting for GPU allocation
- ●running - Processing on GPU
- ●completed - Successfully finished
- ●failed - Execution error
- ●canceled - Canceled by user
# GET /tasks/{task_id}
# Check the status of a task
curl "https://api.runkey.ai/v1/tasks/task_8f3a2b" \
-H "Authorization: Bearer rk_live_xxxxx"
# Response (Running):
# {
# "code": 0,
# "data": {
# "task_id": "task_8f3a2b",
# "template_id": "tpl_portrait_fix",
# "status": "running",
# "progress": 65,
# "created_at": "2026-03-23T00:00:00Z",
# "started_at": "2026-03-23T00:00:02Z"
# }
# }
# Response (Completed):
# {
# "code": 0,
# "data": {
# "task_id": "task_8f3a2b",
# "status": "completed",
# "output": {
# "result_url": "https://cdn.runkey.ai/results/task_8f3a2b.png"
# },
# "processing_time": 8.2,
# "credits_used": 15
# }
# }Task Result
When a task completes, the response includes the output object with template-specific results.
Response Fields
output | Template output (URLs, data, etc.) |
processing_time | Execution time in seconds |
credits_used | Credits consumed |
# Task Status Values
# - queued: Waiting for GPU allocation
# - running: Processing on GPU
# - completed: Successfully finished
# - failed: Execution error
# - canceled: Canceled by user
# Completed task response structure:
{
"code": 0,
"data": {
"task_id": "task_8f3a2b",
"template_id": "tpl_portrait_fix",
"status": "completed",
"input": {
"image_url": "https://example.com/photo.jpg",
"enhancement": "high"
},
"output": {
"result_url": "https://cdn.runkey.ai/results/xxx.png",
"thumbnail_url": "https://cdn.runkey.ai/thumbs/xxx.jpg"
},
"created_at": "2026-03-23T00:00:00Z",
"started_at": "2026-03-23T00:00:02Z",
"completed_at": "2026-03-23T00:00:10Z",
"processing_time": 8.2,
"credits_used": 15
}
}Webhooks
Instead of polling, configure a webhook URL to receive task completion notifications automatically.
Event Types
- ●
task.completed- Task finished successfully - ●
task.failed- Task execution failed
Signature Verification
Verify the X-RunKey-Signature header using HMAC-SHA256 with your webhook secret.
# Configure webhook in your template settings or per-request
# RunKey will POST to your URL when the task completes
# Webhook payload structure:
{
"event": "task.completed",
"timestamp": "2026-03-23T00:00:10Z",
"data": {
"task_id": "task_8f3a2b",
"template_id": "tpl_portrait_fix",
"status": "completed",
"output": {
"result_url": "https://cdn.runkey.ai/results/xxx.png"
},
"processing_time": 8.2,
"credits_used": 15
},
"signature": "sha256=abc123..."
}
# Verify webhook signature
# signature = HMAC-SHA256(payload, webhook_secret)Error Handling
All error responses include a code and msg field.
Common Error Codes
40001 | Invalid or missing API key |
40002 | Insufficient credits |
40003 | Rate limit exceeded |
40004 | Template not found |
50001 | Internal server error |
# Error Response Format
{
"code": 40001,
"msg": "Invalid API key",
"request_id": "req_abc123"
}
# Common Error Codes:
# 40001 - Invalid or missing API key
# 40002 - Insufficient credits
# 40003 - Rate limit exceeded
# 40004 - Template not found
# 40005 - Invalid input parameters
# 40006 - Task not found
# 50001 - Internal server error
# 50002 - GPU unavailable
# 50003 - Task execution timeout
# HTTP Status Codes:
# 200 - Success
# 400 - Bad Request
# 401 - Unauthorized
# 403 - Forbidden
# 404 - Not Found
# 429 - Too Many Requests
# 500 - Internal Server Error
# 503 - Service UnavailableRate Limits
API requests are rate-limited per account. Check response headers for current limits.
Rate Limit Headers
X-RateLimit-Limit | Max requests per minute |
X-RateLimit-Remaining | Remaining requests |
X-RateLimit-Reset | Reset timestamp (Unix) |
Default Limits
60 req/min, 10 concurrent tasks per account.
# Rate Limit Headers
# X-RateLimit-Limit: 60 (requests per minute)
# X-RateLimit-Remaining: 45 (remaining requests)
# X-RateLimit-Reset: 1679529600 (reset timestamp)
# Example response headers:
HTTP/1.1 200 OK
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1679529600
X-Request-Id: req_abc123
# When rate limited (429 Too Many Requests):
{
"code": 40003,
"msg": "Rate limit exceeded. Please retry after 30 seconds.",
"retry_after": 30
}
# Default Limits by Plan:
# Free: 30 requests/minute, 5 concurrent tasks
# Pro: 60 requests/minute, 10 concurrent tasks
# Team: 120 requests/minute, 25 concurrent tasks