openapi: 3.1.0 info: # Do not change the title, if the title changes, the import paths will be broken title: Api version: 0.1.0 description: API specification servers: - url: /api description: Base API path tags: - name: health description: Health operations - name: jobs description: Payment-gated agent job operations - name: demo description: Free demo endpoint (rate-limited) paths: /healthz: get: operationId: healthCheck tags: [health] summary: Health check description: Returns server health status responses: "200": description: Healthy content: application/json: schema: $ref: "#/components/schemas/HealthStatus" /jobs: post: operationId: createJob tags: [jobs] summary: Create a new agent job description: Accepts a request, creates a job row, and issues an eval fee Lightning invoice. requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateJobRequest" responses: "201": description: Job created successfully content: application/json: schema: $ref: "#/components/schemas/CreateJobResponse" "400": description: Invalid request body content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "500": description: Server error content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /jobs/{id}: get: operationId: getJob tags: [jobs] summary: Get job status description: Returns current job state. Automatically advances the state machine when a pending invoice is found to be paid. parameters: - name: id in: path required: true schema: type: string responses: "200": description: Job status content: application/json: schema: $ref: "#/components/schemas/JobStatusResponse" "404": description: Job not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "500": description: Server error content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /jobs/{id}/refund: post: operationId: claimRefund tags: [jobs] summary: Claim a refund for overpayment description: | After a job completes, if the actual cost (tokens used + infra + margin) was less than the work invoice amount, the difference is owed back to the user. Submit a BOLT11 invoice for exactly `refundAmountSats` to receive the payment. Idempotent: returns 409 if already paid or if no refund is owed. parameters: - name: id in: path required: true schema: type: string requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/ClaimRefundRequest" responses: "200": description: Refund sent content: application/json: schema: $ref: "#/components/schemas/ClaimRefundResponse" "400": description: Missing invoice, wrong amount, or invalid BOLT11 content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "404": description: Job not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "409": description: Job not complete, refund already paid, or no refund owed content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "500": description: Server error (e.g. Lightning payment failure) content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /demo: get: operationId: runDemo tags: [demo] summary: Free demo (rate-limited) description: Runs the agent without payment. Limited to 5 requests per IP per hour. parameters: - name: request in: query required: true schema: type: string responses: "200": description: Demo result content: application/json: schema: $ref: "#/components/schemas/DemoResponse" "400": description: Missing or invalid request param content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "429": description: Rate limit exceeded content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "500": description: Server error content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" components: schemas: HealthStatus: type: object properties: status: type: string required: - status ErrorResponse: type: object required: - error properties: error: type: string InvoiceInfo: type: object required: - paymentRequest - amountSats properties: paymentRequest: type: string amountSats: type: integer CreateJobRequest: type: object required: - request properties: request: type: string minLength: 1 CreateJobResponse: type: object required: - jobId - evalInvoice properties: jobId: type: string evalInvoice: $ref: "#/components/schemas/InvoiceInfo" JobState: type: string enum: - awaiting_eval_payment - evaluating - rejected - awaiting_work_payment - executing - complete - failed PricingBreakdown: type: object description: Cost breakdown shown with the work invoice (estimations at invoice-creation time) properties: estimatedCostUsd: type: number description: Total estimated cost in USD (token cost + DO infra + margin) marginPct: type: number description: Originator margin percentage applied btcPriceUsd: type: number description: BTC/USD spot price used to convert the invoice to sats CostLedger: type: object description: Honest post-work accounting stored after the job completes properties: actualInputTokens: type: integer actualOutputTokens: type: integer totalTokens: type: integer description: Sum of actualInputTokens + actualOutputTokens actualCostUsd: type: number description: Raw Anthropic token cost (no infra, no margin) actualChargeUsd: type: number description: What we honestly charged in USD (actual token cost + DO infra + margin) estimatedCostUsd: type: number description: Original estimate used to create the work invoice actualAmountSats: type: integer description: Honest sats charge (actual cost converted at the locked BTC price) workAmountSats: type: integer description: Amount the user originally paid in sats refundAmountSats: type: integer description: Sats owed back to the user (workAmountSats - actualAmountSats, >= 0) refundState: type: string enum: [not_applicable, pending, paid] description: Lifecycle of the refund for this job marginPct: type: number btcPriceUsd: type: number description: BTC/USD price locked at invoice creation time JobStatusResponse: type: object required: - jobId - state properties: jobId: type: string state: $ref: "#/components/schemas/JobState" evalInvoice: $ref: "#/components/schemas/InvoiceInfo" workInvoice: $ref: "#/components/schemas/InvoiceInfo" pricingBreakdown: $ref: "#/components/schemas/PricingBreakdown" reason: type: string result: type: string costLedger: $ref: "#/components/schemas/CostLedger" errorMessage: type: string ClaimRefundRequest: type: object required: - invoice properties: invoice: type: string description: BOLT11 invoice for exactly refundAmountSats ClaimRefundResponse: type: object required: - ok - refundAmountSats - paymentHash - message properties: ok: type: boolean refundAmountSats: type: integer paymentHash: type: string message: type: string DemoResponse: type: object required: - result properties: result: type: string