{"openapi":"3.1.0","info":{"title":"JJJMR Agentic Data Platform API","description":"Request a data pipeline in plain language. Receive a quote with the plan and the price. Order the quote and pay over x402. Receive a Docker image that runs the pipeline and serves the results over MCP.\n\nStart at `/.well-known/agent-card.json`. `GET /v1/catalog` lists what the platform can build. `POST /v1/quotes` turns an intent into a quote. `POST /v1/orders` answers `402` with the price. Send the same request with a signed payment in the `PAYMENT-SIGNATURE` header and receive `202` with an order token. The platform builds and tests the image, settles the payment and then opens `GET /v1/orders/{order_id}/artifact`. A lost order token is recovered with the wallet that paid, in one of two ways. Send `POST /v1/orders` again with the same body and a fresh payment authorization of that wallet. The platform does not settle it. Or sign a message: `POST /v1/orders/{order_id}/recovery-challenge`, then `POST /v1/orders/{order_id}/recovery`.\n\nEvery error response has the body `{\"error\": {\"code\": ..., \"message\": ..., \"retryable\": ..., \"details\": ...}}`. `code` is one of the values of the `ErrorCode` schema. `details` is an object or `null`. A request that does not match its schema answers `invalid_request` with HTTP 422. An unknown path answers `not_found` with HTTP 404. A known path with another HTTP method answers `method_not_allowed` with HTTP 405 and an `Allow` header. The `402` of a request without a payment is not an error body: it is the x402 `PaymentRequired` object.\n","version":"0.1.39"},"servers":[{"url":"https://jjjmr.cf.keboola.dev"}],"paths":{"/.well-known/agent-card.json":{"get":{"tags":["discovery"],"summary":"Get the A2A agent card","description":"Entry point of discovery. The card links to the OpenAPI document and to the catalog.","operationId":"get_agent_card","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentCard"}}}}}}},"/v1/catalog":{"get":{"tags":["discovery"],"summary":"Get the catalog","description":"What the platform can build.\n\n`sources` and `steps` list the step types that a plan can use. `capabilities` groups the\ntypes that can replace each other, for example the OCR members. `storage` lists the\n`STORAGE_URI` forms of the delivered image: a directory or the buyer's Postgres.","operationId":"get_catalog","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Catalog"}}}}}}},"/.well-known/x402":{"get":{"tags":["discovery"],"summary":"Get the payment terms","description":"The wallet, the networks and the highest price. The wallet is the `payTo` of every 402.","operationId":"get_x402_terms","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WellKnownX402"}}}}}}},"/v1/quotes":{"post":{"tags":["quotes"],"summary":"Request a quote","description":"Send an intent. The status of the answer is `needs_input`, `quoted` or `unsupported`.\n\nWith `needs_input`, answer the questions at the `answer` link in `next`. The same quote ID\ncontinues. With `quoted`, read the plan and the price. Then order at the `order` link.","operationId":"create_quote","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/NeedsInputQuote"},{"$ref":"#/components/schemas/QuotedQuote"},{"$ref":"#/components/schemas/UnsupportedQuote"},{"$ref":"#/components/schemas/ExpiredQuote"}],"title":"Response Create Quote","discriminator":{"propertyName":"status","mapping":{"needs_input":"#/components/schemas/NeedsInputQuote","quoted":"#/components/schemas/QuotedQuote","unsupported":"#/components/schemas/UnsupportedQuote","expired":"#/components/schemas/ExpiredQuote"}}}}}},"422":{"description":"`invalid_request`: The request does not match the schema. Fix the request and send it again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"},"examples":{"invalid_request":{"value":{"error":{"code":"invalid_request","message":"The request does not match the schema. Fix the request and send it again.","retryable":false}}}}}}},"503":{"description":"`planner_unavailable`: The planner cannot answer now. Send the same request again after the seconds that the `Retry-After` header gives.","headers":{"Retry-After":{"description":"The seconds to wait before the same request.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"},"examples":{"planner_unavailable":{"value":{"error":{"code":"planner_unavailable","message":"The planner cannot answer now. Send the same request again after the seconds that the `Retry-After` header gives.","retryable":true}}}}}}}}}},"/v1/quotes/{quote_id}":{"get":{"tags":["quotes"],"summary":"Get a quote","description":"Return the current state of a quote. After `expires_at` the status is `expired`.","operationId":"get_quote","parameters":[{"name":"quote_id","in":"path","required":true,"schema":{"type":"string","format":"uuid4","title":"Quote Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/NeedsInputQuote"},{"$ref":"#/components/schemas/QuotedQuote"},{"$ref":"#/components/schemas/UnsupportedQuote"},{"$ref":"#/components/schemas/ExpiredQuote"}],"discriminator":{"propertyName":"status","mapping":{"needs_input":"#/components/schemas/NeedsInputQuote","quoted":"#/components/schemas/QuotedQuote","unsupported":"#/components/schemas/UnsupportedQuote","expired":"#/components/schemas/ExpiredQuote"}},"title":"Response Get Quote"}}}},"422":{"description":"`invalid_request`: The request does not match the schema. Fix the request and send it again.","content":{"application/json":{"examples":{"invalid_request":{"value":{"error":{"code":"invalid_request","message":"The request does not match the schema. Fix the request and send it again.","retryable":false}}}},"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"`quote_not_found`: No quote has this ID.","content":{"application/json":{"examples":{"quote_not_found":{"value":{"error":{"code":"quote_not_found","message":"No quote has this ID.","retryable":false}}}},"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/quotes/{quote_id}/answers":{"post":{"tags":["quotes"],"summary":"Answer the questions of a quote","description":"Answer open questions. A question with a default can stay open: the default applies.\n\nThe quote becomes `quoted` when all questions without a default have answers. Then it\naccepts no more answers.","operationId":"answer_quote","parameters":[{"name":"quote_id","in":"path","required":true,"schema":{"type":"string","format":"uuid4","title":"Quote Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnswersRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/NeedsInputQuote"},{"$ref":"#/components/schemas/QuotedQuote"},{"$ref":"#/components/schemas/UnsupportedQuote"},{"$ref":"#/components/schemas/ExpiredQuote"}],"discriminator":{"propertyName":"status","mapping":{"needs_input":"#/components/schemas/NeedsInputQuote","quoted":"#/components/schemas/QuotedQuote","unsupported":"#/components/schemas/UnsupportedQuote","expired":"#/components/schemas/ExpiredQuote"}},"title":"Response Answer Quote"}}}},"422":{"description":"`invalid_request`: The request does not match the schema. Fix the request and send it again.","content":{"application/json":{"examples":{"invalid_request":{"value":{"error":{"code":"invalid_request","message":"The request does not match the schema. Fix the request and send it again.","retryable":false}}}},"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"`quote_not_found`: No quote has this ID.","content":{"application/json":{"examples":{"quote_not_found":{"value":{"error":{"code":"quote_not_found","message":"No quote has this ID.","retryable":false}}}},"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"410":{"description":"`quote_expired`: The quote expired. Request a new quote.","content":{"application/json":{"examples":{"quote_expired":{"value":{"error":{"code":"quote_expired","message":"The quote expired. Request a new quote.","retryable":false}}}},"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"400":{"description":"`invalid_answer`: An answer names a question that is not open, or its value does not match the schema of the question. `details.question_ids` lists these questions.","content":{"application/json":{"examples":{"invalid_answer":{"value":{"error":{"code":"invalid_answer","message":"An answer names a question that is not open, or its value does not match the schema of the question. `details.question_ids` lists these questions.","retryable":false,"details":{"question_ids":["fetch.cities"]}}}}},"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"409":{"description":"`not_awaiting_input`: The quote has no open question. Only a quote with the status `needs_input` takes answers.","content":{"application/json":{"examples":{"not_awaiting_input":{"value":{"error":{"code":"not_awaiting_input","message":"The quote has no open question. Only a quote with the status `needs_input` takes answers.","retryable":false}}}},"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"503":{"description":"`planner_unavailable`: The planner cannot answer now. Send the same request again after the seconds that the `Retry-After` header gives.","content":{"application/json":{"examples":{"planner_unavailable":{"value":{"error":{"code":"planner_unavailable","message":"The planner cannot answer now. Send the same request again after the seconds that the `Retry-After` header gives.","retryable":true}}}},"schema":{"$ref":"#/components/schemas/ErrorBody"}}},"headers":{"Retry-After":{"description":"The seconds to wait before the same request.","schema":{"type":"integer"}}}}}}},"/v1/orders":{"post":{"tags":["orders"],"summary":"Order a quoted pipeline and pay over x402","description":"Send `{\"quote_id\": ...}`. Without a payment header the answer is 402.\n\nBefore the 402, the platform checks the body. A body that does not match the schema gets\n422 `invalid_request`. A known quote that has expired gets 410 `quote_expired`. A known\nquote in another status gets 409 `quote_not_quoted`. A quote ID that the platform does not\nknow, or no body, gets the 402 with the listed price. A quote that has an order keeps its\n402, so a buyer can recover access after the quote expired.\n\nThe 402 has the price of the quote in the `PAYMENT-REQUIRED` header, once for each network\nin `accepts`: Base Sepolia (test USDC) and Base mainnet (real USDC). Sign one entry as it\nis and send the same request with the `PAYMENT-SIGNATURE` header. A payment that matches\nno entry gets 402 `payment_invalid`. The answer is 202 with the order ID and the order\ntoken. No money moves at this point: the platform builds and tests the image first and\nsettles the payment after the test, on the network of the entry that you signed.\nThe same authorization again returns the same order, never a second one. The `token` is\nthen null after the settlement started or after an access recovery.\n\nA new authorization of the wallet that paid, for the same quote, never creates a second\norder. The platform verifies it and the answer has a token. Before the settlement it is a\nnew payment of the order. After the settlement started it is an access recovery: the\nplatform does not settle it, the token is new and the old token stops working. Use it\nwhen the order token is lost. The order stays reachable after the quote expires. An\nauthorization recovers access once.","operationId":"create_order","parameters":[{"name":"PAYMENT-SIGNATURE","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The signed x402 payment, base64 JSON. Without it the answer is 402.","title":"Payment-Signature"},"description":"The signed x402 payment, base64 JSON. Without it the answer is 402."},{"name":"X-PAYMENT","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The same as `PAYMENT-SIGNATURE`.","title":"X-Payment"},"description":"The same as `PAYMENT-SIGNATURE`."}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderAccepted"}}}},"422":{"description":"`invalid_request`: The request does not match the schema. Fix the request and send it again.","content":{"application/json":{"examples":{"invalid_request":{"value":{"error":{"code":"invalid_request","message":"The request does not match the schema. Fix the request and send it again.","retryable":false}}}},"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"`quote_not_found`: No quote has this ID.","content":{"application/json":{"examples":{"quote_not_found":{"value":{"error":{"code":"quote_not_found","message":"No quote has this ID.","retryable":false}}}},"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"410":{"description":"`quote_expired`: The quote expired. Request a new quote.","content":{"application/json":{"examples":{"quote_expired":{"value":{"error":{"code":"quote_expired","message":"The quote expired. Request a new quote.","retryable":false}}}},"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"409":{"description":"`quote_not_quoted`: The quote has no price yet. Only a quote with the status `quoted` can be ordered. `details.status` gives the status of the quote.","content":{"application/json":{"examples":{"quote_not_quoted":{"value":{"error":{"code":"quote_not_quoted","message":"The quote has no price yet. Only a quote with the status `quoted` can be ordered. `details.status` gives the status of the quote.","retryable":false,"details":{"status":"needs_input"}}}}},"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"402":{"description":"Without a payment header the body is the x402 `PaymentRequired` object, the same JSON as the `PAYMENT-REQUIRED` header. `insufficient_funds`: The paying wallet does not hold the price. No order exists. `details.reason` and `details.message` give the answer of the facilitator. Fund the wallet, sign a new authorization and send the request again. `payment_invalid`: The payment authorization is not valid. `details.reason` says why. The platform sets these reasons: `invalid_payment_header`: The header is not base64 JSON of an x402 payload. `unsupported_x402_version`: The payment is not x402 version 2. `unsupported_payload`: The payload has no transfer authorization with `from`, `nonce` and `validBefore`. `payment_not_offered`: `accepted` of the payment matches no entry of `accepts`. `authorization_nonce_used`: The nonce belongs to another payment or another order. Any other reason is the reason of the facilitator, for example `invalid_exact_evm_payload_authorization_valid_before`. Sign a new authorization for the terms in the `PAYMENT-REQUIRED` header.","content":{"application/json":{"examples":{"insufficient_funds":{"value":{"error":{"code":"insufficient_funds","message":"The paying wallet does not hold the price. No order exists. `details.reason` and `details.message` give the answer of the facilitator. Fund the wallet, sign a new authorization and send the request again.","retryable":false,"details":{"reason":"insufficient_funds"}}}},"payment_invalid":{"value":{"error":{"code":"payment_invalid","message":"The payment authorization is not valid. `details.reason` says why. The platform sets these reasons: `invalid_payment_header`: The header is not base64 JSON of an x402 payload. `unsupported_x402_version`: The payment is not x402 version 2. `unsupported_payload`: The payload has no transfer authorization with `from`, `nonce` and `validBefore`. `payment_not_offered`: `accepted` of the payment matches no entry of `accepts`. `authorization_nonce_used`: The nonce belongs to another payment or another order. Any other reason is the reason of the facilitator, for example `invalid_exact_evm_payload_authorization_valid_before`. Sign a new authorization for the terms in the `PAYMENT-REQUIRED` header.","retryable":false,"details":{"reason":"invalid_exact_evm_payload_authorization_valid_before"}}}}},"schema":{"anyOf":[{"$ref":"#/components/schemas/ErrorBody"},{"$ref":"#/components/schemas/PaymentRequired"}],"title":"Response 402 Create Order"}}},"headers":{"PAYMENT-REQUIRED":{"description":"The payment terms: base64 of the x402 `PaymentRequired` JSON.","schema":{"type":"string"}}}},"503":{"description":"`facilitator_unavailable`: The payment facilitator cannot answer now. No order exists and nothing is charged. Send the same request again after the seconds that the `Retry-After` header gives.","content":{"application/json":{"examples":{"facilitator_unavailable":{"value":{"error":{"code":"facilitator_unavailable","message":"The payment facilitator cannot answer now. No order exists and nothing is charged. Send the same request again after the seconds that the `Retry-After` header gives.","retryable":true}}}},"schema":{"$ref":"#/components/schemas/ErrorBody"}}},"headers":{"Retry-After":{"description":"The seconds to wait before the same request.","schema":{"type":"integer"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"additionalProperties":false,"properties":{"quote_id":{"description":"The ID of a quote with the status `quoted`.","format":"uuid4","title":"Quote Id","type":"string"}},"required":["quote_id"],"title":"OrderRequest","type":"object"}}}},"x-payment-info":{"protocols":["x402"],"price":{"mode":"dynamic","currency":"USD","min":"0.001","max":"0.10"}}}},"/v1/orders/{order_id}":{"get":{"tags":["orders"],"summary":"Get the status of an order","description":"The phase, the estimate and the payment authorization of the order.\n\n`authorization_expires_at` is always present. The artifact link and the `settlement` of\nthe payment appear after delivery. After the settlement the `PAYMENT-RESPONSE` header has\nthe same settlement.","operationId":"get_order","security":[{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"order_id","in":"path","required":true,"schema":{"type":"string","format":"uuid4","title":"Order Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderStatusView"}}},"headers":{"PAYMENT-RESPONSE":{"description":"The settlement of the payment: base64 of the x402 `SettleResponse` JSON. Present only after the settlement.","schema":{"type":"string"}}}},"422":{"description":"`invalid_request`: The request does not match the schema. Fix the request and send it again.","content":{"application/json":{"examples":{"invalid_request":{"value":{"error":{"code":"invalid_request","message":"The request does not match the schema. Fix the request and send it again.","retryable":false}}}},"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"`not_order_holder`: The request has no valid order token. Send the token as `X-Order-Token: <token>`. The alternative is `Authorization: Bearer <token>`, which some buyer wallets remove. Two different tokens in one request are refused. The same code answers for an ID that no order has, so the answer does not show whether an order exists. To get a new token, recover access with the wallet that paid, in one of two ways. Send `POST /v1/orders` again with the same body and a fresh payment authorization of the wallet. Or use `POST /v1/orders/{order_id}/recovery-challenge` and `POST /v1/orders/{order_id}/recovery` (wallet signature).","content":{"application/json":{"examples":{"not_order_holder":{"value":{"error":{"code":"not_order_holder","message":"The request has no valid order token. Send the token as `X-Order-Token: <token>`. The alternative is `Authorization: Bearer <token>`, which some buyer wallets remove. Two different tokens in one request are refused. The same code answers for an ID that no order has, so the answer does not show whether an order exists. To get a new token, recover access with the wallet that paid, in one of two ways. Send `POST /v1/orders` again with the same body and a fresh payment authorization of the wallet. Or use `POST /v1/orders/{order_id}/recovery-challenge` and `POST /v1/orders/{order_id}/recovery` (wallet signature).","retryable":false}}}},"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/orders/{order_id}/payment":{"post":{"tags":["orders"],"summary":"Send a fresh payment authorization for an order","description":"Replace the payment authorization of an order. The price is the price of the order.\n\nThe 402 lists every network, as the 402 of `POST /v1/orders` does. The new authorization\nmay use another network than the first one. Only the wallet that paid the order can send\nit. The platform accepts it at any time before the settlement starts. An order in\n`payment_required` goes on to the settlement.","operationId":"renew_order_payment","security":[{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"order_id","in":"path","required":true,"schema":{"type":"string","format":"uuid4","title":"Order Id"}},{"name":"PAYMENT-SIGNATURE","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The signed x402 payment, base64 JSON. Without it the answer is 402.","title":"Payment-Signature"},"description":"The signed x402 payment, base64 JSON. Without it the answer is 402."},{"name":"X-PAYMENT","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The same as `PAYMENT-SIGNATURE`.","title":"X-Payment"},"description":"The same as `PAYMENT-SIGNATURE`."}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderStatusView"}}}},"422":{"description":"`invalid_request`: The request does not match the schema. Fix the request and send it again.","content":{"application/json":{"examples":{"invalid_request":{"value":{"error":{"code":"invalid_request","message":"The request does not match the schema. Fix the request and send it again.","retryable":false}}}},"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"`not_order_holder`: The request has no valid order token. Send the token as `X-Order-Token: <token>`. The alternative is `Authorization: Bearer <token>`, which some buyer wallets remove. Two different tokens in one request are refused. The same code answers for an ID that no order has, so the answer does not show whether an order exists. To get a new token, recover access with the wallet that paid, in one of two ways. Send `POST /v1/orders` again with the same body and a fresh payment authorization of the wallet. Or use `POST /v1/orders/{order_id}/recovery-challenge` and `POST /v1/orders/{order_id}/recovery` (wallet signature). `wrong_payer`: Only the wallet that paid the order can send a new authorization for it.","content":{"application/json":{"examples":{"not_order_holder":{"value":{"error":{"code":"not_order_holder","message":"The request has no valid order token. Send the token as `X-Order-Token: <token>`. The alternative is `Authorization: Bearer <token>`, which some buyer wallets remove. Two different tokens in one request are refused. The same code answers for an ID that no order has, so the answer does not show whether an order exists. To get a new token, recover access with the wallet that paid, in one of two ways. Send `POST /v1/orders` again with the same body and a fresh payment authorization of the wallet. Or use `POST /v1/orders/{order_id}/recovery-challenge` and `POST /v1/orders/{order_id}/recovery` (wallet signature).","retryable":false}}},"wrong_payer":{"value":{"error":{"code":"wrong_payer","message":"Only the wallet that paid the order can send a new authorization for it.","retryable":false}}}},"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"409":{"description":"`order_not_payable`: The order takes no new authorization. It is settling, delivered or failed. `details.status` gives the status.","content":{"application/json":{"examples":{"order_not_payable":{"value":{"error":{"code":"order_not_payable","message":"The order takes no new authorization. It is settling, delivered or failed. `details.status` gives the status.","retryable":false,"details":{"status":"delivered"}}}}},"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"402":{"description":"Without a payment header the body is the x402 `PaymentRequired` object, the same JSON as the `PAYMENT-REQUIRED` header. `insufficient_funds`: The paying wallet does not hold the price. No order exists. `details.reason` and `details.message` give the answer of the facilitator. Fund the wallet, sign a new authorization and send the request again. `payment_invalid`: The payment authorization is not valid. `details.reason` says why. The platform sets these reasons: `invalid_payment_header`: The header is not base64 JSON of an x402 payload. `unsupported_x402_version`: The payment is not x402 version 2. `unsupported_payload`: The payload has no transfer authorization with `from`, `nonce` and `validBefore`. `payment_not_offered`: `accepted` of the payment matches no entry of `accepts`. `authorization_nonce_used`: The nonce belongs to another payment or another order. Any other reason is the reason of the facilitator, for example `invalid_exact_evm_payload_authorization_valid_before`. Sign a new authorization for the terms in the `PAYMENT-REQUIRED` header.","content":{"application/json":{"examples":{"insufficient_funds":{"value":{"error":{"code":"insufficient_funds","message":"The paying wallet does not hold the price. No order exists. `details.reason` and `details.message` give the answer of the facilitator. Fund the wallet, sign a new authorization and send the request again.","retryable":false,"details":{"reason":"insufficient_funds"}}}},"payment_invalid":{"value":{"error":{"code":"payment_invalid","message":"The payment authorization is not valid. `details.reason` says why. The platform sets these reasons: `invalid_payment_header`: The header is not base64 JSON of an x402 payload. `unsupported_x402_version`: The payment is not x402 version 2. `unsupported_payload`: The payload has no transfer authorization with `from`, `nonce` and `validBefore`. `payment_not_offered`: `accepted` of the payment matches no entry of `accepts`. `authorization_nonce_used`: The nonce belongs to another payment or another order. Any other reason is the reason of the facilitator, for example `invalid_exact_evm_payload_authorization_valid_before`. Sign a new authorization for the terms in the `PAYMENT-REQUIRED` header.","retryable":false,"details":{"reason":"invalid_exact_evm_payload_authorization_valid_before"}}}}},"schema":{"anyOf":[{"$ref":"#/components/schemas/ErrorBody"},{"$ref":"#/components/schemas/PaymentRequired"}],"title":"Response 402 Renew Order Payment"}}},"headers":{"PAYMENT-REQUIRED":{"description":"The payment terms: base64 of the x402 `PaymentRequired` JSON.","schema":{"type":"string"}}}},"503":{"description":"`facilitator_unavailable`: The payment facilitator cannot answer now. No order exists and nothing is charged. Send the same request again after the seconds that the `Retry-After` header gives.","content":{"application/json":{"examples":{"facilitator_unavailable":{"value":{"error":{"code":"facilitator_unavailable","message":"The payment facilitator cannot answer now. No order exists and nothing is charged. Send the same request again after the seconds that the `Retry-After` header gives.","retryable":true}}}},"schema":{"$ref":"#/components/schemas/ErrorBody"}}},"headers":{"Retry-After":{"description":"The seconds to wait before the same request.","schema":{"type":"integer"}}}}},"x-payment-info":{"protocols":["x402"],"price":{"mode":"dynamic","currency":"USD","min":"0.001","max":"0.10"}}}},"/v1/orders/{order_id}/artifact":{"get":{"tags":["orders"],"summary":"Get the image, the manifest and the test report","description":"The delivery. It opens after the platform settled the payment.\n\nThe answer has the `settlement` of the payment and the `PAYMENT-RESPONSE` header.","operationId":"get_order_artifact","security":[{"HTTPBearer":[]},{"APIKeyHeader":[]}],"parameters":[{"name":"order_id","in":"path","required":true,"schema":{"type":"string","format":"uuid4","title":"Order Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Artifact"}}},"headers":{"PAYMENT-RESPONSE":{"description":"The settlement of the payment: base64 of the x402 `SettleResponse` JSON. Present only after the settlement.","schema":{"type":"string"}}}},"422":{"description":"`invalid_request`: The request does not match the schema. Fix the request and send it again.","content":{"application/json":{"examples":{"invalid_request":{"value":{"error":{"code":"invalid_request","message":"The request does not match the schema. Fix the request and send it again.","retryable":false}}}},"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"`not_order_holder`: The request has no valid order token. Send the token as `X-Order-Token: <token>`. The alternative is `Authorization: Bearer <token>`, which some buyer wallets remove. Two different tokens in one request are refused. The same code answers for an ID that no order has, so the answer does not show whether an order exists. To get a new token, recover access with the wallet that paid, in one of two ways. Send `POST /v1/orders` again with the same body and a fresh payment authorization of the wallet. Or use `POST /v1/orders/{order_id}/recovery-challenge` and `POST /v1/orders/{order_id}/recovery` (wallet signature).","content":{"application/json":{"examples":{"not_order_holder":{"value":{"error":{"code":"not_order_holder","message":"The request has no valid order token. Send the token as `X-Order-Token: <token>`. The alternative is `Authorization: Bearer <token>`, which some buyer wallets remove. Two different tokens in one request are refused. The same code answers for an ID that no order has, so the answer does not show whether an order exists. To get a new token, recover access with the wallet that paid, in one of two ways. Send `POST /v1/orders` again with the same body and a fresh payment authorization of the wallet. Or use `POST /v1/orders/{order_id}/recovery-challenge` and `POST /v1/orders/{order_id}/recovery` (wallet signature).","retryable":false}}}},"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"409":{"description":"`not_delivered`: The order is not delivered. The artifact opens after the settlement. Poll the order status. `details.status` gives the status.","content":{"application/json":{"examples":{"not_delivered":{"value":{"error":{"code":"not_delivered","message":"The order is not delivered. The artifact opens after the settlement. Poll the order status. `details.status` gives the status.","retryable":false,"details":{"status":"building"}}}}},"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/orders/{order_id}/recovery-challenge":{"post":{"tags":["orders"],"summary":"Request a challenge to recover access to an order","description":"Create a challenge for the access recovery of an order. No token is needed.\n\nThe answer is an EIP-4361 message for the wallet that paid the order. The challenge works\nonce and expires after 5 minutes. It is useless without the signature of that wallet.\nSign the message unchanged and send it to `POST /v1/orders/{order_id}/recovery`.","operationId":"request_recovery_challenge","parameters":[{"name":"order_id","in":"path","required":true,"schema":{"type":"string","format":"uuid4","title":"Order Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecoveryChallengeView"}}}},"422":{"description":"`invalid_request`: The request does not match the schema. Fix the request and send it again.","content":{"application/json":{"examples":{"invalid_request":{"value":{"error":{"code":"invalid_request","message":"The request does not match the schema. Fix the request and send it again.","retryable":false}}}},"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"`order_not_found`: No order has this ID. The routes that take the order token answer `not_order_holder` for an unknown ID, so only a request with a token that was valid for the ID gets this code there.","content":{"application/json":{"examples":{"order_not_found":{"value":{"error":{"code":"order_not_found","message":"No order has this ID. The routes that take the order token answer `not_order_holder` for an unknown ID, so only a request with a token that was valid for the ID gets this code there.","retryable":false}}}},"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/orders/{order_id}/recovery":{"post":{"tags":["orders"],"summary":"Recover access to an order with a wallet signature","description":"Send the signed challenge. The answer has a new order token and the status.\n\nOnly the wallet that paid the order can recover access. The old token stops working.\nThe signature is an EIP-191 `personal_sign` signature of an externally owned account.\nSmart-contract wallets (EIP-1271) are not supported. Every failure gives\n`recovery_failed`, so the answer does not tell why.","operationId":"recover_order_access","parameters":[{"name":"order_id","in":"path","required":true,"schema":{"type":"string","format":"uuid4","title":"Order Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecoveryRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecoveredAccess"}}}},"422":{"description":"`invalid_request`: The request does not match the schema. Fix the request and send it again.","content":{"application/json":{"examples":{"invalid_request":{"value":{"error":{"code":"invalid_request","message":"The request does not match the schema. Fix the request and send it again.","retryable":false}}}},"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"`order_not_found`: No order has this ID. The routes that take the order token answer `not_order_holder` for an unknown ID, so only a request with a token that was valid for the ID gets this code there.","content":{"application/json":{"examples":{"order_not_found":{"value":{"error":{"code":"order_not_found","message":"No order has this ID. The routes that take the order token answer `not_order_holder` for an unknown ID, so only a request with a token that was valid for the ID gets this code there.","retryable":false}}}},"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"`recovery_failed`: The recovery request does not prove access to the order. Request a new challenge and sign the message that it returns, unchanged, with the wallet that paid.","content":{"application/json":{"examples":{"recovery_failed":{"value":{"error":{"code":"recovery_failed","message":"The recovery request does not prove access to the order. Request a new challenge and sign the message that it returns, unchanged, with the wallet that paid.","retryable":false}}}},"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}}},"components":{"schemas":{"AgentCard":{"properties":{"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"version":{"type":"string","title":"Version"},"documentationUrl":{"type":"string","title":"Documentationurl"},"capabilities":{"$ref":"#/components/schemas/Capabilities"},"defaultInputModes":{"items":{"type":"string"},"type":"array","title":"Defaultinputmodes"},"defaultOutputModes":{"items":{"type":"string"},"type":"array","title":"Defaultoutputmodes"},"skills":{"items":{"$ref":"#/components/schemas/Skill"},"type":"array","title":"Skills"},"supportedInterfaces":{"items":{"$ref":"#/components/schemas/Interface"},"type":"array","title":"Supportedinterfaces"}},"type":"object","required":["name","description","version","documentationUrl","capabilities","defaultInputModes","defaultOutputModes","skills","supportedInterfaces"],"title":"AgentCard"},"AlternativeOption":{"properties":{"type":{"type":"string","title":"Type","description":"The step type. List it in the answer."},"choice_note":{"type":"string","title":"Choice Note"},"env":{"items":{"$ref":"#/components/schemas/OptionEnvVar"},"type":"array","title":"Env","description":"The env vars that the buyer must set for this option, and its secret env vars. The config_schema of the quote also lists the optional settings."},"price":{"anyOf":[{"$ref":"#/components/schemas/OptionPrice"},{"type":"null"}],"description":"The price of this quote when the plan uses only this option."},"external":{"type":"boolean","title":"External","description":"True when this option sends the data out of the image."}},"type":"object","required":["type","choice_note","env","external"],"title":"AlternativeOption"},"AnswersRequest":{"properties":{"answers":{"additionalProperties":true,"type":"object","minProperties":1,"title":"Answers","description":"Answers by question ID, or by `key` for a `value` question. Do not send the key and the ID of one question. A question with a default can stay open."}},"additionalProperties":false,"type":"object","required":["answers"],"title":"AnswersRequest"},"Artifact":{"properties":{"image":{"type":"string","title":"Image","description":"The image reference to pull. The host is the public registry."},"manifest":{"additionalProperties":true,"type":"object","title":"Manifest","description":"How to run the image: command, env and ports."},"test_report":{"additionalProperties":true,"type":"object","title":"Test Report","description":"The report of the trial run before delivery."},"settlement":{"$ref":"#/components/schemas/Settlement","description":"The settled payment of the order."}},"type":"object","required":["image","manifest","test_report","settlement"],"title":"Artifact"},"Capabilities":{"properties":{"streaming":{"type":"boolean","title":"Streaming","default":false},"pushNotifications":{"type":"boolean","title":"Pushnotifications","default":false},"extensions":{"items":{"$ref":"#/components/schemas/X402Extension"},"type":"array","title":"Extensions"}},"type":"object","required":["extensions"],"title":"Capabilities"},"Capability":{"properties":{"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"members":{"items":{"type":"string"},"type":"array","title":"Members","description":"The step types that fill the capability. Each is in `sources` or `steps`."},"buyer_decides":{"type":"boolean","title":"Buyer Decides","description":"True when the quote asks the buyer which member to use, for example because the members need different keys."},"outcomes":{"items":{"$ref":"#/components/schemas/CapabilityOutcome"},"type":"array","title":"Outcomes","description":"The outcomes that every member has."},"fallback_on":{"items":{"type":"string"},"type":"array","title":"Fallback On","description":"The outcomes after which the next member of the buyer's list runs."}},"type":"object","required":["name","description","members","buyer_decides","outcomes","fallback_on"],"title":"Capability"},"CapabilityOutcome":{"properties":{"name":{"type":"string","title":"Name"},"criterion":{"type":"string","title":"Criterion"}},"type":"object","required":["name","criterion"],"title":"CapabilityOutcome"},"Catalog":{"properties":{"sources":{"items":{"$ref":"#/components/schemas/Source"},"type":"array","title":"Sources"},"steps":{"items":{"type":"string"},"type":"array","title":"Steps","description":"The type of every step that is not a source. `step_types` describes them."},"step_types":{"items":{"$ref":"#/components/schemas/Step"},"type":"array","title":"Step Types","description":"The steps of `steps`, with their details."},"capabilities":{"items":{"$ref":"#/components/schemas/Capability"},"type":"array","title":"Capabilities","description":"The groups of step types that can replace each other."},"storage":{"items":{"$ref":"#/components/schemas/StorageOption"},"type":"array","title":"Storage","description":"The values that `STORAGE_URI` of the delivered image accepts."},"outputs":{"items":{"$ref":"#/components/schemas/McpOutput"},"type":"array","title":"Outputs"},"prices":{"items":{"$ref":"#/components/schemas/PriceEntry"},"type":"array","title":"Prices"}},"type":"object","required":["sources","steps","step_types","capabilities","storage","outputs","prices"],"title":"Catalog"},"CatalogPrice":{"properties":{"amount":{"type":"string","title":"Amount","description":"The listed price in USD. The 402 without a quote offers it. A quote sets the real price, between `amount` and `max_amount`."},"amount_atomic":{"type":"string","title":"Amount Atomic","description":"`amount` in atomic units of the asset."},"asset":{"type":"string","title":"Asset","description":"The USDC contract on `network`. `networks` has the USDC contract of every network."},"network":{"type":"string","title":"Network","description":"The first network of `networks`, Base Sepolia. Kept for older clients. Sign the entry of `accepts` for the network that you pay on."},"pay_to":{"type":"string","title":"Pay To"},"x402_scheme":{"type":"string","title":"X402 Scheme"},"max_amount":{"type":"string","title":"Max Amount","description":"The ceiling of a quote price in USD. It is the `max_per_call_usd` of `/.well-known/x402`."},"max_amount_atomic":{"type":"string","title":"Max Amount Atomic","description":"`max_amount` in atomic units of the asset."},"networks":{"items":{"$ref":"#/components/schemas/PriceNetwork"},"type":"array","title":"Networks","description":"The networks that accept the payment, with the USDC contract and the amount in atomic units of each. The order can be paid on any listed network. The 402 of `POST /v1/orders` offers the same entries.","readOnly":true}},"type":"object","required":["amount","amount_atomic","asset","network","pay_to","x402_scheme","max_amount","max_amount_atomic","networks"],"title":"CatalogPrice","description":"The price of a work kind in the catalog: the listed price and the ceiling of a quote."},"ConfigSchema":{"properties":{"required":{"items":{"$ref":"#/components/schemas/EnvVar"},"type":"array","title":"Required"},"optional":{"items":{"$ref":"#/components/schemas/EnvVar"},"type":"array","title":"Optional"}},"type":"object","required":["required","optional"],"title":"ConfigSchema"},"Delivery":{"properties":{"promised_minutes":{"type":"integer","title":"Promised Minutes"}},"type":"object","required":["promised_minutes"],"title":"Delivery"},"Dependencies":{"properties":{"network_hosts":{"items":{"type":"string"},"type":"array","title":"Network Hosts","description":"Hosts that the image calls."},"runtime_platform":{"type":"string","title":"Runtime Platform"},"port":{"type":"integer","title":"Port","description":"The port of the MCP endpoint."},"peak_memory_mib":{"type":"integer","title":"Peak Memory Mib","description":"An estimate of the peak memory of the image in MiB: the runtime plus the models of its steps, from measurements on sample data. Larger files can need more."}},"type":"object","required":["network_hosts","runtime_platform","port","peak_memory_mib"],"title":"Dependencies"},"EnvVar":{"properties":{"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"placeholder":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Placeholder"}},"type":"object","required":["name","description"],"title":"EnvVar","description":"An environment variable of the delivered image, set by the buyer at `docker run`."},"ErrorBody":{"properties":{"error":{"$ref":"#/components/schemas/ErrorDetail"}},"type":"object","required":["error"],"title":"ErrorBody"},"ErrorCode":{"type":"string","enum":["invalid_request","quote_not_found","quote_expired","invalid_answer","not_awaiting_input","planner_unavailable","quote_not_quoted","insufficient_funds","payment_invalid","facilitator_unavailable","not_order_holder","order_not_found","wrong_payer","order_not_payable","not_delivered","recovery_failed","not_found","method_not_allowed"],"title":"ErrorCode"},"ErrorDetail":{"properties":{"code":{"$ref":"#/components/schemas/ErrorCode"},"message":{"type":"string","title":"Message"},"retryable":{"type":"boolean","title":"Retryable"},"details":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Details","description":"Data for the code, for example the question IDs of `invalid_answer`."}},"type":"object","required":["code","message","retryable","details"],"title":"ErrorDetail"},"ExpiredQuote":{"properties":{"quote_id":{"type":"string","title":"Quote Id","description":"A UUIDv4."},"expires_at":{"type":"string","format":"date-time","title":"Expires At","description":"30 minutes after the last request that created the quote or answered its questions. After this time the status is `expired`."},"intent":{"type":"string","title":"Intent"},"status":{"type":"string","const":"expired","title":"Status","default":"expired"}},"type":"object","required":["quote_id","expires_at","intent"],"title":"ExpiredQuote","description":"The time in `expires_at` has passed. The quote has no plan and no price. Request a new one."},"Interface":{"properties":{"url":{"type":"string","title":"Url"},"protocolBinding":{"type":"string","title":"Protocolbinding"},"protocolVersion":{"type":"string","title":"Protocolversion"}},"type":"object","required":["url","protocolBinding","protocolVersion"],"title":"Interface"},"McpOutput":{"properties":{"type":{"type":"string","const":"mcp","title":"Type","default":"mcp"},"transport":{"type":"string","title":"Transport"},"path":{"type":"string","title":"Path"},"port":{"type":"integer","title":"Port"},"builtin_tools":{"items":{"type":"string"},"type":"array","title":"Builtin Tools"},"domain_tools":{"type":"string","title":"Domain Tools"}},"type":"object","required":["transport","path","port","builtin_tools","domain_tools"],"title":"McpOutput"},"McpTool":{"properties":{"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"input_schema":{"additionalProperties":true,"type":"object","title":"Input Schema"},"builtin":{"type":"boolean","title":"Builtin","description":"True for the three tools that every image offers."}},"type":"object","required":["name","description","input_schema","builtin"],"title":"McpTool"},"NeedsInputQuote":{"properties":{"quote_id":{"type":"string","title":"Quote Id","description":"A UUIDv4."},"expires_at":{"type":"string","format":"date-time","title":"Expires At","description":"30 minutes after the last request that created the quote or answered its questions. After this time the status is `expired`."},"intent":{"type":"string","title":"Intent"},"status":{"type":"string","const":"needs_input","title":"Status","default":"needs_input"},"answers":{"additionalProperties":true,"type":"object","title":"Answers","description":"The values that the quote knows by question ID, from the intent and answers."},"questions":{"items":{"$ref":"#/components/schemas/Question"},"type":"array","title":"Questions"},"next":{"additionalProperties":{"$ref":"#/components/schemas/NextAction"},"type":"object","title":"Next"}},"type":"object","required":["quote_id","expires_at","intent","answers","questions","next"],"title":"NeedsInputQuote"},"NextAction":{"properties":{"method":{"type":"string","enum":["GET","POST"],"title":"Method"},"url":{"type":"string","title":"Url"},"body":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Body","description":"A body template. A null value is a value that you must fill."}},"type":"object","required":["method","url"],"title":"NextAction"},"OptionEnvVar":{"properties":{"name":{"type":"string","title":"Name"},"secret":{"type":"boolean","title":"Secret"},"required":{"type":"boolean","title":"Required"}},"type":"object","required":["name","secret","required"],"title":"OptionEnvVar"},"OptionPrice":{"properties":{"amount":{"type":"string","title":"Amount","description":"The price of this quote with this option, in USDC."},"amount_atomic":{"type":"string","title":"Amount Atomic"},"asset":{"type":"string","title":"Asset"}},"type":"object","required":["amount","amount_atomic","asset"],"title":"OptionPrice"},"OrderAccepted":{"properties":{"order_id":{"type":"string","title":"Order Id"},"token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Token","description":"The access token of the order. Send it as `X-Order-Token: <token>` or as `Authorization: Bearer <token>` to the status, the payment and the artifact routes. Null when the same authorization is sent again after the settlement started or after an access recovery."},"status":{"$ref":"#/components/schemas/OrderStatus"},"status_url":{"type":"string","title":"Status Url"},"authorization_expires_at":{"type":"string","format":"date-time","title":"Authorization Expires At","description":"The payment authorization stops working at this time."},"promised_delivery_at":{"type":"string","format":"date-time","title":"Promised Delivery At","description":"The time that the quote promised for the delivery."},"estimated_completion_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Estimated Completion At","description":"The platform's current estimate for the delivery. Null when it has none."}},"type":"object","required":["order_id","token","status","status_url","authorization_expires_at","promised_delivery_at","estimated_completion_at"],"title":"OrderAccepted","description":"The answer to a paid order request. No money has moved yet."},"OrderStatus":{"type":"string","enum":["accepted","building","testing","ready","payment_required","settling","delivered","failed"],"title":"OrderStatus"},"OrderStatusView":{"properties":{"order_id":{"type":"string","title":"Order Id"},"status":{"$ref":"#/components/schemas/OrderStatus"},"phase":{"type":"string","title":"Phase","description":"What the platform does now, in one sentence."},"status_url":{"type":"string","title":"Status Url"},"artifact_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Artifact Url","description":"Set when the order is delivered."},"authorization_expires_at":{"type":"string","format":"date-time","title":"Authorization Expires At","description":"The stored payment authorization stops working at this time. After it the order waits in `payment_required` for a fresh authorization."},"promised_delivery_at":{"type":"string","format":"date-time","title":"Promised Delivery At"},"estimated_completion_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Estimated Completion At","description":"The current estimate for the delivery. Null when the order is not moving."},"settlement":{"anyOf":[{"$ref":"#/components/schemas/Settlement"},{"type":"null"}],"description":"The settled payment. Set when the order is delivered, else null."},"failure_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Reason","description":"`build_failed`, `build_error`, `build_lost` or `payment_timeout`. Set when the order failed."},"failure_detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Detail"}},"type":"object","required":["order_id","status","phase","status_url","artifact_url","authorization_expires_at","promised_delivery_at","estimated_completion_at","settlement","failure_reason","failure_detail"],"title":"OrderStatusView"},"PaymentRequired":{"properties":{"x402Version":{"type":"integer","title":"X402Version","default":2},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"resource":{"anyOf":[{"$ref":"#/components/schemas/ResourceInfo"},{"type":"null"}]},"accepts":{"items":{"$ref":"#/components/schemas/PaymentRequirements"},"type":"array","title":"Accepts"},"extensions":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Extensions"}},"type":"object","required":["accepts"],"title":"PaymentRequired","description":"V2 402 response structure.\n\nAttributes:\n    x402_version: Protocol version (always 2 for V2).\n    error: Optional error message.\n    resource: Optional resource information.\n    accepts: List of accepted payment requirements.\n    extensions: Optional extension data."},"PaymentRequirements":{"properties":{"scheme":{"type":"string","title":"Scheme"},"network":{"type":"string","title":"Network"},"asset":{"type":"string","title":"Asset"},"amount":{"type":"string","title":"Amount"},"payTo":{"type":"string","title":"Payto"},"maxTimeoutSeconds":{"type":"integer","title":"Maxtimeoutseconds"},"extra":{"additionalProperties":true,"type":"object","title":"Extra"}},"type":"object","required":["scheme","network","asset","amount","payTo","maxTimeoutSeconds"],"title":"PaymentRequirements","description":"V2 payment requirements structure.\n\nAttributes:\n    scheme: Payment scheme identifier (e.g., \"exact\").\n    network: CAIP-2 network identifier (e.g., \"eip155:8453\").\n    asset: Asset address/identifier.\n    amount: Amount in smallest unit.\n    pay_to: Recipient address.\n    max_timeout_seconds: Maximum time for payment validity.\n    extra: Additional scheme-specific data."},"Price":{"properties":{"amount":{"type":"string","title":"Amount"},"amount_atomic":{"type":"string","title":"Amount Atomic"},"asset":{"type":"string","title":"Asset","description":"The USDC contract on `network`. `networks` has the USDC contract of every network."},"network":{"type":"string","title":"Network","description":"The first network of `networks`, Base Sepolia. Kept for older clients. Sign the entry of `accepts` for the network that you pay on."},"pay_to":{"type":"string","title":"Pay To"},"x402_scheme":{"type":"string","title":"X402 Scheme"},"networks":{"items":{"$ref":"#/components/schemas/PriceNetwork"},"type":"array","title":"Networks","description":"The networks that accept the payment, with the USDC contract and the amount in atomic units of each. The order can be paid on any listed network. The 402 of `POST /v1/orders` offers the same entries.","readOnly":true}},"type":"object","required":["amount","amount_atomic","asset","network","pay_to","x402_scheme","networks"],"title":"Price"},"PriceEntry":{"properties":{"work_kind":{"$ref":"#/components/schemas/WorkKind"},"price":{"$ref":"#/components/schemas/CatalogPrice"}},"type":"object","required":["work_kind","price"],"title":"PriceEntry"},"PriceNetwork":{"properties":{"network":{"type":"string","title":"Network","description":"The CAIP-2 identifier of the network."},"asset":{"type":"string","title":"Asset","description":"The USDC contract on this network."},"amount":{"type":"string","title":"Amount","description":"The price in atomic units of the asset, as in `accepts`. Equal on every network."}},"type":"object","required":["network","asset","amount"],"title":"PriceNetwork","description":"A network that the order can be paid on. The 402 has an `accepts` entry for it."},"Question":{"properties":{"id":{"type":"string","title":"Id","description":"`<step_id>.<param>`, `<step_id>.type` or `<capability>.alternative`. A question that has an answer never comes back with the same ID. A step ID can differ between two quotes of one request: use `key` to match a `value` question across quotes."},"kind":{"$ref":"#/components/schemas/QuestionKind","description":"`value`: a parameter of a step has no value. `choice`: the plan has no selection between step types. `alternative`: list one or more options of a capability in the order to try them. The answer applies to every step of that capability in the plan."},"schema":{"additionalProperties":true,"type":"object","title":"Schema","description":"The JSON Schema of the answer."},"default":{"anyOf":[{"type":"string"},{"type":"integer"},{"type":"number"},{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Default","description":"The value that applies when the question stays open. A question without a default needs an answer."},"key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key","description":"For a `value` question: `<step type>.<param>`, for example `confluence.space.base_url`. A plan with two steps of one type numbers them in plan order: `confluence.space#1.base_url`. The key stays the same across quotes. You can send it in the answer in place of the ID, but not both."},"suggested":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Suggested","description":"A recommended answer. It does not apply by itself: send it as the answer to accept it, same shape as the answer."},"text":{"type":"string","title":"Text"},"options":{"anyOf":[{"items":{"$ref":"#/components/schemas/AlternativeOption"},"type":"array"},{"type":"null"}],"title":"Options","description":"The options of an `alternative` question, with their data."},"env":{"items":{"$ref":"#/components/schemas/OptionEnvVar"},"type":"array","title":"Env","description":"For a `value` question: the credentials and other env vars that the buyer must set for the step of this parameter, and its secret env vars. Empty when the step needs none. The config_schema of the quote also lists the optional settings.","default":[]}},"type":"object","required":["id","kind","schema","text"],"title":"Question"},"QuestionKind":{"type":"string","enum":["value","choice","alternative"],"title":"QuestionKind"},"QuoteRequest":{"properties":{"intent":{"type":"string","maxLength":2000,"minLength":1,"title":"Intent","description":"What the pipeline must do, in plain language."},"hints":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Hints","description":"Optional hints, for example source, storage and schedule. The weather quote does not use them yet."}},"additionalProperties":false,"type":"object","required":["intent"],"title":"QuoteRequest"},"QuotedQuote":{"properties":{"quote_id":{"type":"string","title":"Quote Id","description":"A UUIDv4."},"expires_at":{"type":"string","format":"date-time","title":"Expires At","description":"30 minutes after the last request that created the quote or answered its questions. After this time the status is `expired`."},"intent":{"type":"string","title":"Intent"},"status":{"type":"string","const":"quoted","title":"Status","default":"quoted"},"answers":{"additionalProperties":true,"type":"object","title":"Answers","description":"The values of the plan by question ID, including the applied defaults."},"work_kind":{"$ref":"#/components/schemas/WorkKind"},"delivery":{"$ref":"#/components/schemas/Delivery"},"price":{"$ref":"#/components/schemas/Price"},"run_cost_estimate":{"$ref":"#/components/schemas/RunCostEstimate"},"plan":{"additionalProperties":true,"type":"object","title":"Plan","description":"The plan.json that the delivered image runs."},"trial":{"$ref":"#/components/schemas/TrialSpec"},"plan_digest":{"type":"string","title":"Plan Digest","description":"SHA-256 of the canonical JSON of `{\"plan\": <plan>, \"trial\": <trial>}`: keys sorted, no spaces, UTF-8. The price and the promised behavior rest on this plan."},"config_schema":{"$ref":"#/components/schemas/ConfigSchema"},"mcp_tools":{"items":{"$ref":"#/components/schemas/McpTool"},"type":"array","title":"Mcp Tools"},"dependencies":{"$ref":"#/components/schemas/Dependencies"},"next":{"additionalProperties":{"$ref":"#/components/schemas/NextAction"},"type":"object","title":"Next"}},"type":"object","required":["quote_id","expires_at","intent","answers","work_kind","delivery","price","run_cost_estimate","plan","trial","plan_digest","config_schema","mcp_tools","dependencies","next"],"title":"QuotedQuote"},"RecoveredAccess":{"properties":{"order_id":{"type":"string","title":"Order Id"},"status":{"$ref":"#/components/schemas/OrderStatus"},"phase":{"type":"string","title":"Phase","description":"What the platform does now, in one sentence."},"status_url":{"type":"string","title":"Status Url"},"artifact_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Artifact Url","description":"Set when the order is delivered."},"authorization_expires_at":{"type":"string","format":"date-time","title":"Authorization Expires At","description":"The stored payment authorization stops working at this time. After it the order waits in `payment_required` for a fresh authorization."},"promised_delivery_at":{"type":"string","format":"date-time","title":"Promised Delivery At"},"estimated_completion_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Estimated Completion At","description":"The current estimate for the delivery. Null when the order is not moving."},"settlement":{"anyOf":[{"$ref":"#/components/schemas/Settlement"},{"type":"null"}],"description":"The settled payment. Set when the order is delivered, else null."},"failure_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Reason","description":"`build_failed`, `build_error`, `build_lost` or `payment_timeout`. Set when the order failed."},"failure_detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Detail"},"token":{"type":"string","title":"Token","description":"The new access token. Send it as `X-Order-Token: <token>` or as `Authorization: Bearer <token>`."}},"type":"object","required":["order_id","status","phase","status_url","artifact_url","authorization_expires_at","promised_delivery_at","estimated_completion_at","settlement","failure_reason","failure_detail","token"],"title":"RecoveredAccess","description":"The status of the order and its new token. The old token does not work any more."},"RecoveryChallengeView":{"properties":{"message":{"type":"string","title":"Message","description":"An EIP-4361 (Sign-In with Ethereum) message. Sign it unchanged with the wallet that paid the order."},"expires_at":{"type":"string","format":"date-time","title":"Expires At","description":"The challenge stops working at this time."}},"type":"object","required":["message","expires_at"],"title":"RecoveryChallengeView","description":"The message that the wallet of the order signs to recover access."},"RecoveryRequest":{"properties":{"message":{"type":"string","maxLength":2000,"title":"Message","description":"The message of the challenge, unchanged."},"signature":{"type":"string","pattern":"^0x[0-9a-fA-F]{130}$","title":"Signature","description":"The EIP-191 signature of the message: 65 bytes as hex with the prefix `0x`."}},"additionalProperties":false,"type":"object","required":["message","signature"],"title":"RecoveryRequest"},"ResourceInfo":{"properties":{"url":{"type":"string","title":"Url"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"mimeType":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mimetype"},"serviceName":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Servicename"},"tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tags"},"iconUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Iconurl"}},"type":"object","required":["url"],"title":"ResourceInfo","description":"Describes the resource being accessed.\n\nAttributes:\n    url: The URL of the resource.\n    description: Optional human-readable description.\n    mime_type: Optional MIME type of the resource.\n    service_name: Optional human-readable service name (≤ 32 chars).\n    tags: Optional topical tags for the service (≤ 5 entries, each ≤ 32 chars).\n    icon_url: Optional absolute http(s) URL to a service icon (≤ 2048 chars).\n\nSee `specs/extensions/bazaar.md` \"Service Metadata on `resource`\" for\nfacilitator-side validation rules applied to service_name / tags / icon_url."},"RunCostEstimate":{"properties":{"llm_tokens":{"type":"integer","title":"Llm Tokens"},"assumption":{"type":"string","title":"Assumption"}},"type":"object","required":["llm_tokens","assumption"],"title":"RunCostEstimate"},"Settlement":{"properties":{"transaction":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Transaction","description":"The hash of the settlement transaction. Null when the network confirmed the transfer but the platform did not find its hash."},"network":{"type":"string","title":"Network","description":"The network of the transaction."},"payer":{"type":"string","title":"Payer","description":"The wallet that paid."},"amount_atomic":{"type":"string","title":"Amount Atomic","description":"The settled amount in the smallest unit of the asset. It equals the quote."}},"type":"object","required":["transaction","network","payer","amount_atomic"],"title":"Settlement","description":"The settled payment of a delivered order. The transaction is public on the network."},"Skill":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags"},"examples":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Examples"}},"type":"object","required":["id","name","description","tags"],"title":"Skill"},"Source":{"properties":{"type":{"type":"string","title":"Type"},"description":{"type":"string","title":"Description","default":""},"credentials":{"items":{"$ref":"#/components/schemas/EnvVar"},"type":"array","title":"Credentials","description":"The env that a plan with this source needs, unless the quote says otherwise. The quote is authoritative: its `config_schema` lists the env of the order. A quote can make the key of a service member optional when a fallback step follows.","default":[]},"optional_env":{"items":{"$ref":"#/components/schemas/EnvVar"},"type":"array","title":"Optional Env","default":[]},"params":{"items":{"$ref":"#/components/schemas/SourceParam"},"type":"array","title":"Params","default":[]}},"type":"object","required":["type"],"title":"Source"},"SourceParam":{"properties":{"name":{"type":"string","title":"Name"},"type":{"$ref":"#/components/schemas/ValueType"},"description":{"type":"string","title":"Description"},"required":{"type":"boolean","title":"Required"},"default":{"title":"Default","description":"The value when the plan leaves it out."}},"type":"object","required":["name","type","description","required"],"title":"SourceParam"},"Step":{"properties":{"type":{"type":"string","title":"Type"},"kind":{"$ref":"#/components/schemas/StepKind","description":"`item` runs for each item of a run. `after_run` runs once after the items. A `source` is listed in `sources`, not here."},"description":{"type":"string","title":"Description"},"capability":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Capability","description":"The capability that this step type fills, a name from `capabilities`. The members of one capability can replace each other. Null for a step type that fills no capability."},"credentials":{"items":{"$ref":"#/components/schemas/EnvVar"},"type":"array","title":"Credentials","description":"The env that a plan with this step needs, unless the quote says otherwise. The quote is authoritative: its `config_schema` lists the env of the order."},"optional_env":{"items":{"$ref":"#/components/schemas/EnvVar"},"type":"array","title":"Optional Env"},"params":{"items":{"$ref":"#/components/schemas/SourceParam"},"type":"array","title":"Params"},"fee":{"type":"integer","title":"Fee","description":"The atomic units of the asset that the step adds to the price of a quote. The price is the base fee plus the fees of all steps of the plan, rounded and limited to the range of the catalog price."}},"type":"object","required":["type","kind","description","capability","credentials","optional_env","params","fee"],"title":"Step"},"StepKind":{"type":"string","enum":["source","item","after_run"]},"StorageOption":{"properties":{"scheme":{"type":"string","title":"Scheme"},"uri_example":{"type":"string","title":"Uri Example"},"description":{"type":"string","title":"Description"}},"type":"object","required":["scheme","uri_example","description"],"title":"StorageOption"},"TrialFixture":{"properties":{"path":{"type":"string","title":"Path","description":"The URL path of the file on the fixture server of the trial."},"sha256":{"type":"string","title":"Sha256","description":"The SHA-256 of the file, in hex."}},"type":"object","required":["path","sha256"],"title":"TrialFixture"},"TrialSpec":{"properties":{"env":{"additionalProperties":{"type":"string"},"type":"object","title":"Env","description":"Environment variables of the image in the trial. `{fixtures}` is the URL of the fixture server."},"fixtures":{"items":{"$ref":"#/components/schemas/TrialFixture"},"type":"array","title":"Fixtures"},"tool_calls":{"items":{"$ref":"#/components/schemas/TrialToolCall"},"type":"array","title":"Tool Calls","description":"One call for each domain tool."}},"type":"object","required":["env","fixtures","tool_calls"],"title":"TrialSpec","description":"What the builder runs on the image before it delivers it. The digest of the quote covers it."},"TrialToolCall":{"properties":{"tool":{"type":"string","title":"Tool"},"args":{"additionalProperties":true,"type":"object","title":"Args","description":"Arguments that fit the input schema of the tool."}},"type":"object","required":["tool","args"],"title":"TrialToolCall"},"UnsupportedQuote":{"properties":{"quote_id":{"type":"string","title":"Quote Id","description":"A UUIDv4."},"expires_at":{"type":"string","format":"date-time","title":"Expires At","description":"30 minutes after the last request that created the quote or answered its questions. After this time the status is `expired`."},"intent":{"type":"string","title":"Intent"},"status":{"type":"string","const":"unsupported","title":"Status","default":"unsupported"},"reason":{"type":"string","title":"Reason"},"supported_sources":{"items":{"type":"string"},"type":"array","title":"Supported Sources"}},"type":"object","required":["quote_id","expires_at","intent","reason","supported_sources"],"title":"UnsupportedQuote"},"ValueType":{"type":"string","enum":["string_array","object_array","number","enum","string","integer","boolean"],"title":"ValueType"},"WellKnownPayment":{"properties":{"payTo":{"type":"string","title":"Payto","description":"The wallet that receives every payment."},"network":{"type":"string","title":"Network","description":"The first network of `networks`, Base Sepolia. Kept for older clients. `networks` lists every network that the quote price and the 402 offer."},"networks":{"items":{"type":"string"},"type":"array","title":"Networks","description":"The CAIP-2 identifier of every network that the 402 offers."},"max_per_call_usd":{"type":"number","title":"Max Per Call Usd","description":"The highest price of one quote, in USD."}},"type":"object","required":["payTo","network","networks","max_per_call_usd"],"title":"WellKnownPayment"},"WellKnownX402":{"properties":{"payment":{"$ref":"#/components/schemas/WellKnownPayment"},"operator":{"type":"string","title":"Operator"},"service":{"type":"string","title":"Service"}},"type":"object","required":["payment","operator","service"],"title":"WellKnownX402"},"WorkKind":{"type":"string","enum":["assemble"],"title":"WorkKind"},"X402Extension":{"properties":{"uri":{"type":"string","title":"Uri"},"description":{"type":"string","title":"Description"},"required":{"type":"boolean","title":"Required"},"params":{"$ref":"#/components/schemas/X402Params"}},"type":"object","required":["uri","description","required","params"],"title":"X402Extension"},"X402Network":{"properties":{"network":{"type":"string","title":"Network"},"asset":{"type":"string","title":"Asset"},"assetName":{"type":"string","title":"Assetname"}},"type":"object","required":["network","asset","assetName"],"title":"X402Network"},"X402Params":{"properties":{"x402Version":{"type":"integer","title":"X402Version"},"scheme":{"type":"string","title":"Scheme"},"network":{"type":"string","title":"Network","description":"The first network of `networks`, Base Sepolia. Kept for older clients. The quote price and the 402 of an order offer every network in `networks`."},"asset":{"type":"string","title":"Asset","description":"The USDC contract on the network above."},"assetName":{"type":"string","title":"Assetname"},"assetDecimals":{"type":"integer","title":"Assetdecimals"},"networks":{"items":{"$ref":"#/components/schemas/X402Network"},"type":"array","title":"Networks","description":"Every network that the 402 offers, in the order of its `accepts`."},"payTo":{"type":"string","title":"Payto"},"maxTimeoutSeconds":{"type":"integer","title":"Maxtimeoutseconds"},"catalogUrl":{"type":"string","title":"Catalogurl"},"quotesUrl":{"type":"string","title":"Quotesurl"},"openapiUrl":{"type":"string","title":"Openapiurl"}},"type":"object","required":["x402Version","scheme","network","asset","assetName","assetDecimals","networks","payTo","maxTimeoutSeconds","catalogUrl","quotesUrl","openapiUrl"],"title":"X402Params"}},"securitySchemes":{"HTTPBearer":{"type":"http","description":"The order token from the 202 answer of `POST /v1/orders`. The header `X-Order-Token` carries it too.","scheme":"bearer"},"APIKeyHeader":{"type":"apiKey","description":"The order token as `X-Order-Token: <token>`. Use it when the client removes `Authorization`, as the Agnes wallet does.","in":"header","name":"X-Order-Token"}}}}