{"openapi":"3.0.3","info":{"title":"Idea Developer API","version":"1.0.0","description":"Public API-key interface for media uploads, dynamic GPU tools, and media publishing. Tool-specific schemas are discovered at GET /tools. Mobile-session and internal APIs are outside this specification.","contact":{"email":"support@4014labs.com"}},"servers":[{"url":"https://dev.67idea.com/v1"}],"externalDocs":{"url":"https://dev.67idea.com/docs"},"security":[{"bearerAuth":[]}],"paths":{"/":{"get":{"operationId":"getApiInfo","summary":"Identify the API and discover documentation","security":[],"responses":{"200":{"description":"API metadata; not a backend health check","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiInfo"}}}}}}},"/openapi.json":{"get":{"operationId":"getOpenApiSpec","summary":"Download the OpenAPI specification","security":[],"responses":{"200":{"description":"OpenAPI document","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/me":{"get":{"operationId":"getApiPrincipal","summary":"Verify the current API key","description":"Requires a valid API key.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Principal"}}}},"401":{"description":"Missing, invalid, expired, or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/tools":{"get":{"operationId":"listTools","summary":"Discover tool names, descriptions, and input schemas","description":"Requires tools:read.","x-required-scopes":["tools:read"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolList"}}}},"401":{"description":"Missing, invalid, expired, or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope or inactive billing account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/uploads":{"post":{"operationId":"authorizeUpload","summary":"Authorize an image or video upload","description":"Requires uploads:create. Returns HTTP 201 with a short-lived upload token and TUS endpoint. Transfer bytes using TUS at that endpoint, with the returned metadata, then poll GET /uploads/{uploadId}. This request does not upload bytes. Supported extensions depend on deployment configuration.","x-required-scopes":["uploads:create"],"responses":{"201":{"description":"Upload authorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadAuthorization"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, expired, or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope or inactive billing account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadRequest"}}}}}},"/uploads/{uploadId}":{"get":{"operationId":"getUpload","summary":"Read upload processing status","description":"Requires uploads:read.","x-required-scopes":["uploads:read"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Upload"}}}},"401":{"description":"Missing, invalid, expired, or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope or inactive billing account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found in this project/environment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream service failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"uploadId","in":"path","required":true,"schema":{"type":"string"}}]}},"/tool-runs":{"post":{"operationId":"createToolRun","summary":"Execute a discovered tool","description":"Requires tools:execute. Discover names and argument schemas with GET /tools. Allow at least 300 seconds for the request. This route waits for execution; a durable run record does not imply background execution. Tool output may contain its own job ID and polling instructions. Timeouts do not guarantee cancellation. Reuse the same Idempotency-Key and body for a retry of the same operation.","x-required-scopes":["tools:execute"],"responses":{"200":{"description":"Existing or replayed run","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolRun"}}}},"201":{"description":"New completed run","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolRun"}}}},"400":{"description":"Request error or failed tool run; inspect error and run status.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/ToolRun"}]}}}},"401":{"description":"Missing, invalid, expired, or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Insufficient API balance","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope or inactive billing account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found in this project/environment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Request error or failed tool run; inspect error and run status.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/ToolRun"}]}}}},"413":{"description":"Request error or failed tool run; inspect error and run status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolRun"}}}},"422":{"description":"Request error or failed tool run; inspect error and run status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolRun"}}}},"429":{"description":"Request error or failed tool run; inspect error and run status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolRun"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Request error or failed tool run; inspect error and run status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolRun"}}}},"503":{"description":"Billing not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"Request error or failed tool run; inspect error and run status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolRun"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolRunRequest"}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Recommended for safe retries. A different body with the same key returns 409.","schema":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[A-Za-z0-9._:-]+$"}}]}},"/tool-runs/{runId}":{"get":{"operationId":"getToolRun","summary":"Read a tool run","description":"Requires runs:read.","x-required-scopes":["runs:read"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolRun"}}}},"401":{"description":"Missing, invalid, expired, or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope or inactive billing account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found in this project/environment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"runId","in":"path","required":true,"schema":{"type":"string"}}]}},"/media/publish":{"post":{"operationId":"publishMedia","summary":"Create temporary viewing and download URLs","description":"Requires media:read. Path must belong to the workspace for this project, environment, and external_user_id. Keep signed URLs out of logs and model transcripts; deliver via the authorized media UI.","x-required-scopes":["media:read"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishedMedia"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, expired, or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope or inactive billing account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Resource not found in this project/environment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Upstream service failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishRequest"}}}}}},"/billing/usage":{"get":{"operationId":"getConsumerUsage","summary":"Discover consumer plan access and billing options","description":"Requires usage:read and a personal developer account. Read-only snapshot, not job authorization. Fast/Standard quotas are not configured yet: null counters do not mean exhausted or unlimited per GPU. Existing unlimited subscription access is preserved. Only offer job top-ups when top_up_available is true; billing_url remains available for plan management. This endpoint does not select a GPU or enable fallback.","x-required-scopes":["usage:read"],"responses":{"200":{"description":"Current consumer access and discovery metadata","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsumerUsage"}}}},"401":{"description":"Missing, invalid, expired, or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing usage:read scope or not a personal developer account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Unable to retrieve usage; do not infer account entitlement","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/billing/balance":{"get":{"operationId":"getBillingBalance","summary":"Read organization API balance","description":"Requires usage:read. Monetary fields are integer strings in micros: 1 USD = 1,000,000 micros. Organization API balance is distinct from web-app balance.","x-required-scopes":["usage:read"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Balance"}}}},"401":{"description":"Missing, invalid, expired, or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Missing scope or inactive billing account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api-keys/current":{"delete":{"operationId":"revokeCurrentApiKey","summary":"Permanently revoke the authenticating key","description":"No extra scope required. Irreversibly revokes this key for all clients; does not revoke already-issued upload tokens before their expiration.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Revocation"}}}},"401":{"description":"Missing, invalid, expired, or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"idea_sk_*","description":"Secret API key from the developer dashboard. Send Authorization: Bearer <key>."}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"],"additionalProperties":true},"ApiInfo":{"type":"object","properties":{"name":{"type":"string","enum":["Idea Developer API"]},"version":{"type":"string","enum":["v1"]},"base_url":{"type":"string","format":"uri"},"documentation_url":{"type":"string","format":"uri"},"openapi_url":{"type":"string","format":"uri"}},"required":["name","version","base_url","documentation_url","openapi_url"],"additionalProperties":true},"Principal":{"type":"object","properties":{"object":{"type":"string","enum":["api_principal"]},"organization_id":{"type":"string"},"project_id":{"type":"string"},"environment":{"type":"string","enum":["test","live"]},"scopes":{"type":"array","items":{"type":"string"}}},"required":["object","organization_id","project_id","environment","scopes"],"additionalProperties":true},"Tool":{"type":"object","properties":{"id":{"type":"string"},"description":{"type":"string"},"input_schema":{"type":"object","additionalProperties":true,"description":"Live JSON Schema describing this tool's arguments."},"required_scopes":{"type":"array","items":{"type":"string"}}},"required":["id","description","input_schema","required_scopes"],"additionalProperties":true},"ToolList":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Tool"}}},"required":["object","data"],"additionalProperties":true},"Upload":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","enum":["upload"]},"workspace_id":{"type":"string"},"status":{"type":"string","enum":["authorized","processing","succeeded","failed"]},"filename":{"type":"string"},"filesize":{"type":"integer"},"filetype":{"type":"string"},"workspace_uri":{"type":"string","nullable":true},"output_filename":{"type":"string","nullable":true},"error":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":true,"nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","object","workspace_id","status","filename","filesize","filetype","workspace_uri","output_filename","error","created_at","updated_at"],"additionalProperties":true},"ToolRun":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","enum":["tool_run"]},"tool":{"type":"string"},"status":{"type":"string","enum":["queued","running","succeeded","failed"]},"environment":{"type":"string","enum":["test","live"]},"input":{"description":"Submitted tool arguments; schema depends on the discovered tool."},"output":{"description":"Tool-dependent JSON output, or null before completion."},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string","nullable":true},"accepted":{"type":"boolean","nullable":true,"description":"Backend acceptance, when known. Null is not a rejection."},"job_id":{"type":"string","nullable":true},"details":{"$ref":"#/components/schemas/ToolFailureDetails"}},"required":["code","message"],"additionalProperties":true,"nullable":true},"created_at":{"type":"string","format":"date-time"},"started_at":{"type":"string","format":"date-time","nullable":true},"finished_at":{"type":"string","format":"date-time","nullable":true}},"required":["id","object","tool","status","environment","input","output","error","created_at","started_at","finished_at"],"additionalProperties":true},"ToolFailureDetails":{"type":"object","required":["accepted","job_id","retryable","recovery"],"properties":{"accepted":{"type":"boolean","nullable":true},"job_id":{"type":"string","nullable":true},"retryable":{"type":"boolean","description":"True only for explicit pre-acceptance 429/503 rejections without evidence of execution. Not permission to resubmit an ambiguous job."},"recovery":{"type":"string","enum":["retry_after_delay","poll_job","inspect_run","correct_request"]},"upstream_status":{"type":"integer","minimum":400,"maximum":599},"retry_after_seconds":{"type":"integer","minimum":0,"maximum":86400}},"description":"Optional on failed runs. Also exposed at the run top level as details, accepted and job_id for SDK compatibility. A failed API run does not establish that an underlying GPU job stopped. Retry an uncertain submission only by the original idempotency key/body; inspect the durable run or poll its backend job first. A confirmed rejected run is terminal: after waiting/correcting the request, a new submission needs a new idempotency key."},"PublishedMedia":{"type":"object","properties":{"object":{"type":"string","enum":["published_media"]},"media_type":{"type":"string","enum":["image","video",null],"nullable":true},"display_url":{"type":"string","format":"uri"},"download_url":{"type":"string","format":"uri"},"expires_unix":{"type":"integer"},"expires_at":{"type":"string","format":"date-time"}},"required":["object","media_type","display_url","download_url","expires_unix","expires_at"],"additionalProperties":true},"ConsumerUsage":{"type":"object","required":["object","contract_version","access","plan","usage_mode","tier_quotas_enabled","tiers","top_up_available","billing_url","automatic_fallback"],"properties":{"object":{"type":"string","enum":["consumer_usage"]},"contract_version":{"type":"integer","enum":[1]},"access":{"type":"string","enum":["active","subscription_required"]},"plan":{"type":"object","nullable":true,"required":["id","name"],"properties":{"id":{"type":"string"},"name":{"type":"string"}}},"usage_mode":{"type":"string","enum":["unlimited","no_plan","shared_credits","gpu_time"]},"gpu_time":{"type":"object","nullable":true,"additionalProperties":true,"description":"GPU-time snapshot when enabled. status is ready or legacy. Ready usage contains perGpu availableSeconds/reservedSeconds and eligibility, usePurchased, purchasedSeconds5090, reservedSeconds5090, activeJobs and unlimited. GPU balances are alternatives from one shared weighted pool, not additive allowances. Legacy means historical balances have not been converted. Discovery only; reservation enforces access."},"render_credits":{"type":"object","nullable":true,"additionalProperties":true,"description":"Account-scoped subscription and PAYG grant totals, remaining, reserved and available credits; applicable plan periods and GPU eligibility. Transfer counters remain null until connected."},"metering_enabled":{"type":"boolean","description":"Whether consumer render enforcement and backend metering readiness are enabled."},"tier_quotas_enabled":{"type":"boolean","enum":[false]},"tiers":{"type":"array","items":{"type":"object","required":["id","name","status","remaining_jobs","resets_at"],"properties":{"id":{"type":"string","enum":["fast","standard"]},"name":{"type":"string"},"status":{"type":"string","enum":["not_configured"]},"remaining_jobs":{"type":"integer","minimum":0,"nullable":true,"description":"Currently null: no tier quota has been configured. Never interpret null as zero."},"resets_at":{"type":"string","format":"date-time","nullable":true,"description":"Currently null; not the subscription renewal date."}}}},"top_up_available":{"type":"boolean","description":"True only when PAYG purchases are enabled and the account has an eligible paid subscription period. Purchased render credits are distinct from legacy cash balances."},"billing_url":{"type":"string","format":"uri"},"automatic_fallback":{"type":"boolean","enum":[false]}}},"Balance":{"type":"object","properties":{"object":{"type":"string","enum":["developer_balance"]},"organization_id":{"type":"string"},"currency":{"type":"string"},"balance_micros":{"type":"string","pattern":"^-?[0-9]+$"},"reserved_micros":{"type":"string","pattern":"^-?[0-9]+$"},"available_micros":{"type":"string","pattern":"^-?[0-9]+$"},"status":{"type":"string"}},"required":["object","organization_id","currency","balance_micros","reserved_micros","available_micros","status"],"additionalProperties":true},"Revocation":{"type":"object","properties":{"object":{"type":"string","enum":["api_key"]},"revoked":{"type":"boolean","enum":[true]}},"required":["object","revoked"],"additionalProperties":true},"UploadAuthorization":{"allOf":[{"$ref":"#/components/schemas/Upload"},{"type":"object","properties":{"upload_endpoint":{"type":"string","format":"uri"},"upload_token":{"type":"string"},"upload_token_expires_at":{"type":"string","format":"date-time"},"tus_metadata":{"type":"object","properties":{"filename":{"type":"string"},"filetype":{"type":"string"},"chatId":{"type":"string"},"userId":{"type":"string"},"uploadId":{"type":"string"}},"required":["filename","filetype","chatId","userId","uploadId"],"additionalProperties":true}},"required":["upload_endpoint","upload_token","upload_token_expires_at","tus_metadata"],"additionalProperties":true}]},"UploadRequest":{"type":"object","properties":{"external_user_id":{"type":"string","minLength":1,"maxLength":255,"description":"Stable external user identifier. Reuse across related uploads, tools, and publishing."},"filename":{"type":"string","minLength":1,"maxLength":255,"description":"Safe basename with a supported image/video extension; no path separators or control characters."},"filesize":{"type":"integer","minimum":1,"maximum":104857600},"filetype":{"type":"string","description":"Image/video MIME type, or an empty string."}},"required":["external_user_id","filename","filesize","filetype"],"additionalProperties":false},"ToolRunRequest":{"type":"object","properties":{"tool":{"type":"string","minLength":1,"maxLength":128},"external_user_id":{"type":"string","minLength":1,"maxLength":255,"description":"Stable external user identifier. Reuse across related uploads, tools, and publishing."},"input":{"type":"object","additionalProperties":true,"description":"Arguments matching input_schema from GET /tools."}},"required":["tool","external_user_id","input"],"additionalProperties":false},"PublishRequest":{"type":"object","properties":{"external_user_id":{"type":"string","minLength":1,"maxLength":255,"description":"Stable external user identifier. Reuse across related uploads, tools, and publishing."},"media_path":{"type":"string","minLength":1,"maxLength":2048},"ttl_seconds":{"type":"integer","minimum":1,"maximum":7200,"default":7200}},"required":["external_user_id","media_path"],"additionalProperties":false}}}}