{"openapi":"3.1.0","info":{"title":"IMD paid requests","version":"1.0.0","description":"Pay for enabled swarm actions with x402 v2 exact ERC-20 payments through Permit2. This document covers the shared paid entrance; other control-plane routes are in the API guide.","x-guidance":"Read capabilities. Generate and retain a random 32-byte secret (64 hex characters) as a Bearer token. Create a quote with a fresh UUID requestKey and action/input. POST an empty body to that order's submit URL for the 402 challenge. Sign the Permit2 payment and IMD's additional EIP-712 quote approval with the same wallet. Resubmit both signatures, then poll the order with the same token. Never pay from discovery metadata; inspect the saved quote and challenge. The payment buys admission, not a guaranteed successful result."},"servers":[{"url":"https://api.imd.fun"}],"externalDocs":{"description":"Paid API flow, action inputs and signing examples","url":"https://imd.fun/docs#paid"},"security":[{"requestToken":[]},{"apiKey":[]}],"x-imd-actions":[{"action":"job.open","version":"job-1","payment":{"network":"eip155:1","asset":"0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7","amount":"500000000000000000","payTo":"0x4e0fa57bde726079356537e2f34d671e9f41adbc","decimals":18},"quoteTtlSeconds":600,"limits":{}},{"action":"job.continue","version":"job-1","payment":{"network":"eip155:1","asset":"0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7","amount":"500000000000000000","payTo":"0x4e0fa57bde726079356537e2f34d671e9f41adbc","decimals":18},"quoteTtlSeconds":600,"limits":{}},{"action":"launch.open","version":"launch-1","payment":{"network":"eip155:1","asset":"0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7","amount":"500000000000000000","payTo":"0x4e0fa57bde726079356537e2f34d671e9f41adbc","decimals":18},"quoteTtlSeconds":600,"limits":{}},{"action":"oracle.request","version":"oracle-1","payment":{"network":"eip155:1","asset":"0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7","amount":"500000000000000000","payTo":"0x4e0fa57bde726079356537e2f34d671e9f41adbc","decimals":18},"quoteTtlSeconds":600,"limits":{"minPanelSize":5,"maxPanelSize":100}},{"action":"workflow.open","version":"workflow-1","payment":{"network":"eip155:1","asset":"0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7","amount":"500000000000000000","payTo":"0x4e0fa57bde726079356537e2f34d671e9f41adbc","decimals":18},"quoteTtlSeconds":600,"limits":{}},{"action":"schedule.create","version":"schedule-1","payment":{"network":"eip155:1","asset":"0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7","amount":"500000000000000000","payTo":"0x4e0fa57bde726079356537e2f34d671e9f41adbc","decimals":18},"quoteTtlSeconds":600,"limits":{"minRuns":1,"maxRuns":1000000,"minOracleIntervalMinutes":10,"minJobIntervalMinutes":30},"pricedPer":"run","note":"payment.amount is the price of one; a quote charges it once per unit bought"},{"action":"schedule.topup","version":"topup-1","payment":{"network":"eip155:1","asset":"0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7","amount":"500000000000000000","payTo":"0x4e0fa57bde726079356537e2f34d671e9f41adbc","decimals":18},"quoteTtlSeconds":600,"limits":{"minRuns":1,"maxRuns":1000000,"minOracleIntervalMinutes":10,"minJobIntervalMinutes":30},"pricedPer":"run","note":"payment.amount is the price of one; a quote charges it once per unit bought"}],"paths":{"/openapi.json":{"get":{"operationId":"paidDiscovery","summary":"Free API discovery document","security":[],"description":"Public metadata only. This document is not itself a paid resource.","responses":{"200":{"description":"OpenAPI 3.1 description of the shared paid API.","content":{"application/json":{"schema":{"type":"object","required":["openapi","info","paths"],"properties":{"openapi":{"type":"string"},"info":{"type":"object"},"paths":{"type":"object"}}}}}},"429":{"description":"Rate limit reached; wait for Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/requests/capabilities":{"get":{"operationId":"paidCapabilities","summary":"Enabled actions, prices and limits","security":[],"responses":{"200":{"description":"Public settings for new quotes. Existing quotes keep their original terms.","content":{"application/json":{"schema":{"type":"object","required":["actions","limits","authentication","payment"],"properties":{"actions":{"type":"array","items":{"$ref":"#/components/schemas/Policy"}},"limits":{"type":"object"},"launches":{"type":"object","description":"The chains a launch can deploy on now: {defaultChainId, chains:[{chainId, name, testnet, kinds, pairings:[{pairWith, currency, symbol, name, decimals, kinds}]}]}. A body's chainId must name one of them."},"authentication":{"type":"object"},"payment":{"type":"object"}}}}}},"429":{"description":"Rate limit reached; wait for Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/requests/quote":{"post":{"operationId":"quotePaidRequest","summary":"Validate input and save a priced order","description":"Creates a quote without charging or dispatching work. Action validation may consult the chain, planner or input judge. Reuse the requestKey when retrying the same input. Sign the returned quote, whose prepared input may differ from the original input.","externalDocs":{"description":"Input schemas for each action","url":"https://imd.fun/docs#paid"},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"action":{"type":"string","enum":["job.open","job.continue","launch.open","oracle.request","workflow.open","schedule.create","schedule.topup"]},"input":{"description":"Action-specific input. See the API payload guide and x-imd-actions. The quote validates and pins it before payment."},"requestKey":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["action","input","requestKey"],"additionalProperties":false}}}},"responses":{"200":{"description":"Saved quote; new orders return 201, retries with the same input and requestKey return 200.","content":{"application/json":{"schema":{"type":"object","required":["created","order"],"properties":{"created":{"type":"boolean"},"order":{"$ref":"#/components/schemas/Order"}}}}},"links":{"challenge":{"operationId":"submitPaidRequest","parameters":{"id":"$response.body#/order/id"}},"status":{"operationId":"getPaidRequest","parameters":{"id":"$response.body#/order/id"}}}},"201":{"description":"Saved quote; new orders return 201, retries with the same input and requestKey return 200.","content":{"application/json":{"schema":{"type":"object","required":["created","order"],"properties":{"created":{"type":"boolean"},"order":{"$ref":"#/components/schemas/Order"}}}}},"links":{"challenge":{"operationId":"submitPaidRequest","parameters":{"id":"$response.body#/order/id"}},"status":{"operationId":"getPaidRequest","parameters":{"id":"$response.body#/order/id"}}}},"400":{"description":"Invalid input or payment approval.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"A client-generated request token is required.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Browser Origin does not match the configured service origin.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Request key or payment conflict; inspect the existing order before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request exceeds the 16 KiB body limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The action refused the input; nothing is charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; wait for Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Temporarily unavailable; saved state is retained.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/requests/{id}/submit":{"post":{"operationId":"submitPaidRequest","summary":"Get a challenge or pay for the saved action","description":"Requires an existing order and its client token. Without PAYMENT-SIGNATURE, omit the body or send {} for the challenge. To pay, send the base64 x402 payload in PAYMENT-SIGNATURE and {quoteSignature} in JSON. Both signatures must use the same wallet. Sign the EIP-712 QuoteApproval in x-imd-quote-approval over the challenge context and the exact payment payload; a standard x402 signature alone is insufficient. The payload is parsed strictly: unknown keys, including any non-empty extensions, fail as invalid_payment_shape with a detail naming the field. Retry the same order; poll while pending.","x-payment-info":{"protocols":[{"x402":{"version":2,"scheme":"exact","assetTransferMethod":"permit2"}}]},"x-imd-quote-approval":{"type":"EIP-712","required":true,"docs":"https://imd.fun/docs#quote-approval","domain":{"name":"IdentityMD Paid Action","version":"1","chainId":"the number in quote.payment.network (eip155:<chainId>)"},"primaryType":"QuoteApproval","types":{"QuoteApproval":[{"name":"resource","type":"string"},{"name":"requesterScopeHash","type":"bytes32"},{"name":"quoteId","type":"string"},{"name":"quoteHash","type":"bytes32"},{"name":"paymentHash","type":"bytes32"},{"name":"action","type":"string"},{"name":"asset","type":"address"},{"name":"amount","type":"uint256"},{"name":"payTo","type":"address"},{"name":"expiresAt","type":"uint256"}]},"message":{"resource":"resourceUrl","requesterScopeHash":"0x + requesterScopeHash","quoteId":"quote.id","quoteHash":"0x + quote.quoteHash","paymentHash":"0x + SHA-256 of the canonical JSON (keys sorted, no whitespace) of the exact payment payload sent in PAYMENT-SIGNATURE","action":"quote.action","asset":"quote.payment.asset","amount":"quote.payment.amount","payTo":"quote.payment.payTo","expiresAt":"quote.expiresAt"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"order.id from POST /requests/quote, accessed with the same client token."},{"name":"PAYMENT-SIGNATURE","in":"header","required":false,"description":"Base64-encoded x402 v2 payment payload. Include quoteSignature in the body when present.","schema":{"type":"string","maxLength":12288}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","additionalProperties":false,"maxProperties":0},{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"quoteSignature":{"type":"string","pattern":"^0x[0-9a-fA-F]{130}$"}},"required":["quoteSignature"],"additionalProperties":false}]}}}},"responses":{"200":{"description":"Saved outcome; inspect status and admission.result.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}}},"202":{"description":"Payment or admission is pending. Poll GET /requests/{id}.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}}},"400":{"description":"Invalid input or payment approval.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"A client-generated request token is required.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Payment challenge, or payment_rejected when verification rejects an approval.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Challenge"},{"$ref":"#/components/schemas/Error"}]}}},"headers":{"PAYMENT-REQUIRED":{"description":"Base64-encoded x402 v2 challenge; present when offering payment.","schema":{"type":"string"}}}},"403":{"description":"Browser Origin does not match the configured service origin.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Order not found or owned by another client token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Request key or payment conflict; inspect the existing order before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"Unpaid quote expired; request a new quote before signing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request exceeds the 16 KiB body limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The action refused the input; nothing is charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; wait for Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Temporarily unavailable; saved state is retained.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/requests/{id}":{"get":{"operationId":"getPaidRequest","summary":"Read saved payment and admission status","description":"Reading does not charge, query the blockchain or start work. Follow admission.result's URLs to observe the created work.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"order.id from POST /requests/quote, accessed with the same client token."}],"responses":{"200":{"description":"Saved order status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}}},"400":{"description":"Invalid input or payment approval.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"A client-generated request token is required.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Browser Origin does not match the configured service origin.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Order not found or owned by another client token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Request key or payment conflict; inspect the existing order before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"Unpaid quote expired; request a new quote before signing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request exceeds the 16 KiB body limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The action refused the input; nothing is charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; wait for Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Temporarily unavailable; saved state is retained.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"requestToken":{"type":"http","scheme":"bearer","bearerFormat":"64 hex characters","description":"Client-generated random 32-byte secret, retained across quotes/retries/status reads. No operator credential or registration is required. This identifies your orders; wallet signatures separately authorize payment. apiKey is a discovery alias for this same Bearer scheme."},"apiKey":{"$ref":"#/components/securitySchemes/requestToken"}},"schemas":{"Policy":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"action":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z][a-z0-9]*(?:[._-][a-z0-9]+)*$"},"version":{"type":"string","minLength":1,"maxLength":64},"payment":{"type":"object","properties":{"network":{"type":"string","maxLength":24,"pattern":"^eip155:[1-9][0-9]*$"},"asset":{"type":"string","pattern":"^0x[0-9a-f]{40}$"},"amount":{"type":"string","pattern":"^(0|[1-9][0-9]{0,77})$"},"payTo":{"type":"string","pattern":"^0x[0-9a-f]{40}$"},"decimals":{"type":"integer","minimum":0,"maximum":255}},"required":["network","asset","amount","payTo","decimals"],"additionalProperties":false},"quoteTtlSeconds":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["action","version","payment","quoteTtlSeconds"],"additionalProperties":false},"Quote":{"$schema":"https://json-schema.org/draft/2020-12/schema","readOnly":true,"type":"object","properties":{"v":{"type":"number","const":1},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"action":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z][a-z0-9]*(?:[._-][a-z0-9]+)*$"},"policyVersion":{"type":"string","minLength":1,"maxLength":64},"inputHash":{"type":"string","pattern":"^[0-9a-f]{64}$"},"issuedAt":{"type":"integer","minimum":0,"maximum":9007199254740991},"expiresAt":{"type":"integer","minimum":0,"maximum":9007199254740991},"payment":{"readOnly":true,"type":"object","properties":{"network":{"type":"string","maxLength":24,"pattern":"^eip155:[1-9][0-9]*$"},"asset":{"type":"string","pattern":"^0x[0-9a-f]{40}$"},"amount":{"type":"string","pattern":"^(0|[1-9][0-9]{0,77})$"},"payTo":{"type":"string","pattern":"^0x[0-9a-f]{40}$"},"decimals":{"type":"integer","minimum":0,"maximum":255},"scheme":{"type":"string","const":"exact"}},"required":["network","asset","amount","payTo","decimals","scheme"],"additionalProperties":false},"unitAmount":{"type":"string","pattern":"^(0|[1-9][0-9]{0,77})$"},"runs":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"payer":{"type":"string","pattern":"^0x[0-9a-f]{40}$"},"terms":{"readOnly":true,"type":"object","properties":{"purchase":{"type":"string","const":"action-admission"},"resultGuaranteed":{"type":"boolean","const":false}},"required":["purchase","resultGuaranteed"],"additionalProperties":false},"quoteHash":{"type":"string","pattern":"^[0-9a-f]{64}$"}},"required":["v","id","action","policyVersion","inputHash","issuedAt","expiresAt","payment","terms","quoteHash"],"additionalProperties":false},"Order":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"requestKey":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"type":"string","enum":["quoted","expired","payment_pending","payment_failed","paid"]},"quote":{"readOnly":true,"type":"object","properties":{"v":{"type":"number","const":1},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"action":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z][a-z0-9]*(?:[._-][a-z0-9]+)*$"},"policyVersion":{"type":"string","minLength":1,"maxLength":64},"inputHash":{"type":"string","pattern":"^[0-9a-f]{64}$"},"issuedAt":{"type":"integer","minimum":0,"maximum":9007199254740991},"expiresAt":{"type":"integer","minimum":0,"maximum":9007199254740991},"payment":{"readOnly":true,"type":"object","properties":{"network":{"type":"string","maxLength":24,"pattern":"^eip155:[1-9][0-9]*$"},"asset":{"type":"string","pattern":"^0x[0-9a-f]{40}$"},"amount":{"type":"string","pattern":"^(0|[1-9][0-9]{0,77})$"},"payTo":{"type":"string","pattern":"^0x[0-9a-f]{40}$"},"decimals":{"type":"integer","minimum":0,"maximum":255},"scheme":{"type":"string","const":"exact"}},"required":["network","asset","amount","payTo","decimals","scheme"],"additionalProperties":false},"unitAmount":{"type":"string","pattern":"^(0|[1-9][0-9]{0,77})$"},"runs":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"payer":{"type":"string","pattern":"^0x[0-9a-f]{40}$"},"terms":{"readOnly":true,"type":"object","properties":{"purchase":{"type":"string","const":"action-admission"},"resultGuaranteed":{"type":"boolean","const":false}},"required":["purchase","resultGuaranteed"],"additionalProperties":false},"quoteHash":{"type":"string","pattern":"^[0-9a-f]{64}$"}},"required":["v","id","action","policyVersion","inputHash","issuedAt","expiresAt","payment","terms","quoteHash"],"additionalProperties":false},"inputJson":{"type":"string"},"createdAt":{"type":"string"},"paidAt":{"type":["string","null"]}},"required":["id","requestKey","status","quote","inputJson","createdAt","paidAt"]},"Status":{"type":"object","required":["status","order","payment","admission"],"properties":{"status":{"type":"string","enum":["quoted","expired","payment_pending","payment_failed","admission_pending","admitted"]},"order":{"$ref":"#/components/schemas/Order"},"payment":{"type":["object","null"],"description":"Saved settlement status, including paid and transactionHash; no signed payment payload."},"admission":{"type":["object","null"],"description":"Saved action result, including its job, oracle or workflow reference when admitted. Admission does not guarantee the work succeeds."}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string"},"detail":{"type":"string"},"reason":{"type":"string"},"problems":{"type":"array","items":{"type":"object"}}}},"Challenge":{"type":"object","required":["x402Version","resource","accepts","quote","requesterScopeHash","resourceUrl","input"],"properties":{"x402Version":{"type":"integer","const":2},"resource":{"type":"object"},"accepts":{"type":"array","minItems":1,"items":{"type":"object","required":["scheme","network","asset","amount","payTo","maxTimeoutSeconds"],"properties":{"scheme":{"type":"string","const":"exact"},"network":{"type":"string"},"asset":{"type":"string"},"amount":{"type":"string","pattern":"^[0-9]+$","description":"Token atomic units, not a decimal token amount or USD."},"payTo":{"type":"string"},"maxTimeoutSeconds":{"type":"integer"},"extra":{"type":"object"}}}},"quote":{"$ref":"#/components/schemas/Quote"},"requesterScopeHash":{"type":"string"},"resourceUrl":{"type":"string","format":"uri"},"input":{"description":"The exact prepared input saved with this quote. Inspect it before signing."}}}}}}