Check, for free, that a target can be tested before you pay. Selo checks the authorization, sends one unpaid request to the target (with requestBody for POST, 10 second timeout, redirects not followed), reads its x402 v2 challenge, and requires an exact USDC payment on Algorand priced at or below the per-job spend limit (0.50 USDC). It also looks the target up in the Bazaar catalog and stores what it finds with the preflight. An eligible preflight is valid for 15 minutes.
JSON body Selo sends to the target on every request of this test. Only with POST. Any JSON value except null, at most 16 KiB (16384 bytes) once serialized. Omit it to send no body.
Response
The target is eligible.
The target can be tested. Pass preflightId to POST /v1/release-test before expiresAt.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Selo","description":"CI for x402. Selo pays your endpoint before your users do.","colors":{"primary":"#EA580C","light":"#FB923C","dark":"#C2410C"},"logo":{"light":"https://mintcdn.com/selo/uDDPP6e9J3oqq-so/logo/light.svg?fit=max\u0026auto=format\u0026n=uDDPP6e9J3oqq-so\u0026q=85\u0026s=34ba3a87bcb123757ba48be31d19069d","dark":"https://mintcdn.com/selo/uDDPP6e9J3oqq-so/logo/dark.svg?fit=max\u0026auto=format\u0026n=uDDPP6e9J3oqq-so\u0026q=85\u0026s=c204c3bd2d3bcf1dcc90d2a9f7fb1f7d","href":"https://useselo.xyz"},"favicon":"https://mintcdn.com/selo/uDDPP6e9J3oqq-so/favicon.png?fit=max\u0026auto=format\u0026n=uDDPP6e9J3oqq-so\u0026q=85\u0026s=523f923af3f56c58eb8696b88a9f4fd7","api":{"playground":{"display":"simple"},"examples":{"languages":["curl","javascript","python"]}},"navbar":{"links":[{"href":"https://github.com/Enoch208/selo","label":"GitHub"}],"primary":{"type":"button","label":"Open Selo","href":"https://useselo.xyz"}},"footer":{"socials":{"x":"https://x.com/useselo_","github":"https://github.com/Enoch208/selo","website":"https://useselo.xyz"}},"seo":{"metatags":{"og:site_name":"Selo docs"}},"contextual":{"options":["copy","view","chatgpt","claude","perplexity","mcp","cursor","vscode"],"display":"header"},"styling":{"latex":false},"navigation":{"global":{"anchors":[{"anchor":"Website","icon":"globe","href":"https://useselo.xyz"},{"anchor":"GitHub","icon":"github","href":"https://github.com/Enoch208/selo"},{"anchor":"Pilot guide","icon":"flag-checkered","href":"https://github.com/Enoch208/selo/blob/main/docs/PILOT_GUIDE.md"}]},"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"selo","hasAudioNarration":false,"actualSubdomain":"selo","customDomains":["docs.useselo.xyz"],"gitSource":{"type":"github","owner":"enoch208","repo":"docs-adrianne","deployBranch":"main","contentDirectory":"","isPrivate":false,"mountPath":"","label":"","_id":"6adfade67d7c0e994635dbe7"},"chroma":{"latestBuiltDeploymentHistoryId":"6adfb6c6e2a550116c3cb359","collectionId":"36784781-278b-473b-a258-a7b58f1f6d68","liveDeploymentHistoryId":"6adfb6c6e2a550116c3cb359","schemaVersion":"v3"},"entitlements":{},"buildId":"6adfb6c6e2a550116c3cb359","clientVersion":"0.0.3971","searchFilterCounts":[{"language":"default","tag":"Documentation","count":25},{"language":"default","tag":"API reference","count":14},{"language":"default","tag":"Endpoints","count":11},{"language":"default","tag":"Guides","count":9},{"language":"default","tag":"CLI reference","count":7},{"language":"default","tag":"Concepts","count":7},{"language":"default","tag":"selo CLI","count":6},{"language":"default","tag":"Resources","count":5},{"language":"default","tag":"Get started","count":4},{"language":"default","tag":"Overview","count":3}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-v7-file-tree","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"pause-universal-search-reconcile","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"per-site-search-delta","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-private-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-nav-generations","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-agent-model-picker","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"isAtlas":false,"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"api-reference/preflight/run-a-preflight","slug":"/api-reference/preflight/run-a-preflight","pageMetadata":{"title":"Run a preflight","description":"Check, for free, that a target can be tested before you pay. Selo checks the authorization, sends one unpaid request to the target (with `requestBody` for `POST`, 10 second timeout, redirects not followed), reads its x402 v2 challenge, and requires an `exact` USDC payment on Algorand priced at or below the per-job spend limit (0.50 USDC). It also looks the target up in the Bazaar catalog and stores what it finds with the preflight. An eligible preflight is valid for 15 minutes.","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/preflight","href":"/api-reference/preflight/run-a-preflight","autogeneratedByOpenApi":true},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx, jsxs: _jsxs} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n code: \"code\",\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsxs(_components.p, {\n children: [\"Check, for free, that a target can be tested before you pay. Selo checks the authorization, sends one unpaid request to the target (with \", _jsx(_components.code, {\n children: \"requestBody\"\n }), \" for \", _jsx(_components.code, {\n children: \"POST\"\n }), \", 10 second timeout, redirects not followed), reads its x402 v2 challenge, and requires an \", _jsx(_components.code, {\n children: \"exact\"\n }), \" USDC payment on Algorand priced at or below the per-job spend limit (0.50 USDC). It also looks the target up in the Bazaar catalog and stores what it finds with the preflight. An eligible preflight is valid for 15 minutes.\"]\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){return _jsx(_Fragment,{})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Run a preflight","description":"Check, for free, that a target can be tested before you pay. Selo checks the authorization, sends one unpaid request to the target (with `requestBody` for `POST`, 10 second timeout, redirects not followed), reads its x402 v2 challenge, and requires an `exact` USDC payment on Algorand priced at or below the per-job spend limit (0.50 USDC). It also looks the target up in the Bazaar catalog and stores what it finds with the preflight. An eligible preflight is valid for 15 minutes.","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/preflight","href":"/api-reference/preflight/run-a-preflight","autogeneratedByOpenApi":true}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":[],"openApiReferenceData":{"operation":{"tags":["Preflight"],"operationId":"createPreflight","summary":"Run a preflight","description":"Check, for free, that a target can be tested before you pay. Selo checks the authorization, sends one unpaid request to the target (with `requestBody` for `POST`, 10 second timeout, redirects not followed), reads its x402 v2 challenge, and requires an `exact` USDC payment on Algorand priced at or below the per-job spend limit (0.50 USDC). It also looks the target up in the Bazaar catalog and stores what it finds with the preflight. An eligible preflight is valid for 15 minutes.","requestBody":"66d853c3-7685-4525-9143-c9391f6378c0","responses":{"201":"47ce021f-2ae5-470e-8427-c9077bcee66c","400":"f90f33e8-058b-4896-8b68-664d2737760d","403":"2f89b615-1fc7-4a6b-92aa-77d0f1bf1412","413":"e69c6907-9815-4f0a-9bb3-f09ba9ab9ede","422":"7a0b6248-8426-4d2a-b733-80c7ab55c40c","500":"93a27636-f957-4bd4-8e25-b9cde0b497e4"},"method":"post","type":"path","servers":["fbe7f743-573d-4126-9bae-6b7b65ed90a1"],"security":[],"path":"/v1/preflight","baseUrlOptions":["https://api.useselo.xyz"],"title":"Run a preflight","codeSamples":[],"requestExampleLanguages":["bash","javascript","python"],"requiredOnlyExamples":false,"requestExampleType":"generated","responseExampleType":"generated"},"dependencies":{"parameters":{},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["authorizationId","targetUrl","method"],"properties":{"authorizationId":{"type":"string","maxLength":64,"description":"A verified authorization that covers this origin, path and method.","isRequired":true,"uniqueKey":"authorizationId","typeLabel":"string"},"targetUrl":{"type":"string","maxLength":2048,"format":"uri","description":"Absolute `https` URL of the paid route. A query string is sent to the target; coverage is checked on origin and path.","isRequired":true,"uniqueKey":"targetUrl","typeLabel":"string\u003curi>"},"method":{"type":"string","enum":["GET","POST"],"description":"HTTP method Selo uses to call the target.","isRequired":true,"uniqueKey":"method","typeLabel":"enum\u003cstring>"},"requestBody":{"oneOf":[{"description":"JSON body Selo sends to the target on every request of this test. Only with `POST`. Any JSON value except `null`, at most 16 KiB (16384 bytes) once serialized. Omit it to send no body.","type":"object","uniqueKey":"requestBody.oneOf.0","typeLabel":"object"},{"description":"JSON body Selo sends to the target on every request of this test. Only with `POST`. Any JSON value except `null`, at most 16 KiB (16384 bytes) once serialized. Omit it to send no body.","type":"array","uniqueKey":"requestBody.oneOf.1","typeLabel":"array"},{"description":"JSON body Selo sends to the target on every request of this test. Only with `POST`. Any JSON value except `null`, at most 16 KiB (16384 bytes) once serialized. Omit it to send no body.","type":"string","uniqueKey":"requestBody.oneOf.2","typeLabel":"string"},{"description":"JSON body Selo sends to the target on every request of this test. Only with `POST`. Any JSON value except `null`, at most 16 KiB (16384 bytes) once serialized. Omit it to send no body.","type":"number","uniqueKey":"requestBody.oneOf.3","typeLabel":"number"},{"description":"JSON body Selo sends to the target on every request of this test. Only with `POST`. Any JSON value except `null`, at most 16 KiB (16384 bytes) once serialized. Omit it to send no body.","type":"boolean","uniqueKey":"requestBody.oneOf.4","typeLabel":"boolean"}],"uniqueKey":"requestBody","typeLabel":"object | array | string | number | boolean"}},"uniqueKey":"","typeLabel":"object"},"examples":{"post":{"title":"post","value":{"authorizationId":"auth_…","targetUrl":"https://api.example.com/v1/orders","method":"POST","requestBody":{"sku":"demo-widget","quantity":1}}},"get":{"title":"get","value":{"authorizationId":"auth_…","targetUrl":"https://api.example.com/v1/quote","method":"GET"}}},"exampleType":"examples"}},"exampleType":"examples"},"responses":{"47ce021f-2ae5-470e-8427-c9077bcee66c":{"description":"The target is eligible.","content":{"application/json":{"schema":{"type":"object","description":"The target can be tested. Pass `preflightId` to `POST /v1/release-test` before `expiresAt`.","required":["eligible","preflightId","target","estimatedMaxSpendUsdc","seloPriceUsdc","expiresAt"],"properties":{"eligible":{"type":"boolean","const":true,"isRequired":true,"uniqueKey":"eligible","typeLabel":"boolean"},"preflightId":{"type":"string","description":"`pfl_` plus 26 Crockford base32 characters.","isRequired":true,"uniqueKey":"preflightId","typeLabel":"string"},"target":{"type":"object","required":["url","method","priceUsdc"],"properties":{"url":{"type":"string","description":"Normalized target URL (fragment removed).","isRequired":true,"uniqueKey":"target.url","typeLabel":"string"},"method":{"type":"string","enum":["GET","POST"],"description":"HTTP method Selo uses to call the target.","isRequired":true,"uniqueKey":"target.method","typeLabel":"enum\u003cstring>"},"priceUsdc":{"type":"string","pattern":"^[0-9]+\\.[0-9]{2,6}$","description":"Price the target asked for in its 402 challenge.","isRequired":true,"uniqueKey":"target.priceUsdc","typeLabel":"string"}},"isRequired":true,"uniqueKey":"target","typeLabel":"object"},"estimatedMaxSpendUsdc":{"type":"string","pattern":"^[0-9]+\\.[0-9]{2,6}$","description":"What Selo expects to pay the target: one paid request at the target's price.","isRequired":true,"uniqueKey":"estimatedMaxSpendUsdc","typeLabel":"string"},"seloPriceUsdc":{"type":"string","pattern":"^[0-9]+\\.[0-9]{2,6}$","description":"What the release test costs you, paid to Selo over x402.","isRequired":true,"uniqueKey":"seloPriceUsdc","typeLabel":"string"},"expiresAt":{"type":"string","format":"date-time","description":"The preflight is valid for 15 minutes.","isRequired":true,"uniqueKey":"expiresAt","typeLabel":"string\u003cdate-time>"}},"uniqueKey":"","typeLabel":"object"},"examples":{"eligible":{"title":"eligible","value":{"eligible":true,"preflightId":"pfl_…","target":{"url":"https://api.example.com/v1/orders","method":"POST","priceUsdc":"0.01"},"estimatedMaxSpendUsdc":"0.01","seloPriceUsdc":"1.00","expiresAt":"2026-10-26T12:15:00.000Z"}}},"exampleType":"examples"}},"exampleType":"examples"},"f90f33e8-058b-4896-8b68-664d2737760d":{"description":"The body fails validation (`ApiError`), or the target URL is invalid or not https (`PreflightIneligible`, `preflightId` is `null`).","content":{"application/json":{"schema":{"oneOf":[{"type":"object","description":"The target cannot be tested. Nothing was paid.","required":["eligible","preflightId","reason","message"],"properties":{"eligible":{"type":"boolean","const":false,"isRequired":true,"uniqueKey":"oneOf.0.eligible","typeLabel":"boolean"},"preflightId":{"oneOf":[{"type":"string","description":"ID of the stored preflight, or `null` when Selo refused the request before storing it (invalid URL, blocked hostname, unknown authorization).","isRequired":true,"uniqueKey":"oneOf.0.preflightId.oneOf.0","typeLabel":"string"},{"type":"null","description":"ID of the stored preflight, or `null` when Selo refused the request before storing it (invalid URL, blocked hostname, unknown authorization).","isRequired":true,"uniqueKey":"oneOf.0.preflightId.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"oneOf.0.preflightId","typeLabel":"string | null"},"reason":{"type":"string","enum":["AUTHORIZATION_MISSING","AUTHORIZATION_EXPIRED","TARGET_URL_INVALID","TARGET_NOT_HTTPS","TARGET_ADDRESS_BLOCKED","METHOD_NOT_ALLOWED","TARGET_UNREACHABLE","NO_PAYMENT_CHALLENGE","NETWORK_NOT_SUPPORTED","ASSET_NOT_SUPPORTED","PRICE_OVER_BUDGET"],"description":"Why a target is not eligible for a release test.","isRequired":true,"uniqueKey":"oneOf.0.reason","typeLabel":"enum\u003cstring>"},"message":{"type":"string","isRequired":true,"uniqueKey":"oneOf.0.message","typeLabel":"string"}},"uniqueKey":"oneOf.0","typeLabel":"object"},{"type":"object","description":"Error body returned by every failing request.","required":["error","message"],"properties":{"error":{"type":"string","description":"Stable machine-readable error code, for example `VALIDATION_FAILED`.","isRequired":true,"uniqueKey":"oneOf.1.error","typeLabel":"string"},"message":{"type":"string","description":"Human-readable explanation. Do not parse it.","isRequired":true,"uniqueKey":"oneOf.1.message","typeLabel":"string"}},"uniqueKey":"oneOf.1","typeLabel":"object"}],"uniqueKey":"","typeLabel":"object"},"examples":{"TARGET_URL_INVALID":{"title":"TARGET_URL_INVALID","value":{"eligible":false,"preflightId":null,"reason":"TARGET_URL_INVALID","message":"The target URL is not a valid absolute URL"}},"TARGET_NOT_HTTPS":{"title":"TARGET_NOT_HTTPS","value":{"eligible":false,"preflightId":null,"reason":"TARGET_NOT_HTTPS","message":"Only https targets can be tested"}},"VALIDATION_FAILED":{"title":"VALIDATION_FAILED","value":{"error":"VALIDATION_FAILED","message":"✖ requestBody is only allowed with POST\n → at requestBody"}}},"exampleType":"examples"}},"exampleType":"examples"},"2f89b615-1fc7-4a6b-92aa-77d0f1bf1412":{"description":"No verified, unexpired authorization covers this origin, path and method. `preflightId` is `null` when the authorization ID is unknown.","content":{"application/json":{"schema":{"type":"object","description":"The target cannot be tested. Nothing was paid.","required":["eligible","preflightId","reason","message"],"properties":{"eligible":{"type":"boolean","const":false,"isRequired":true,"uniqueKey":"eligible","typeLabel":"boolean"},"preflightId":{"oneOf":[{"type":"string","description":"ID of the stored preflight, or `null` when Selo refused the request before storing it (invalid URL, blocked hostname, unknown authorization).","isRequired":true,"uniqueKey":"preflightId.oneOf.0","typeLabel":"string"},{"type":"null","description":"ID of the stored preflight, or `null` when Selo refused the request before storing it (invalid URL, blocked hostname, unknown authorization).","isRequired":true,"uniqueKey":"preflightId.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"preflightId","typeLabel":"string | null"},"reason":{"type":"string","enum":["AUTHORIZATION_MISSING","AUTHORIZATION_EXPIRED","TARGET_URL_INVALID","TARGET_NOT_HTTPS","TARGET_ADDRESS_BLOCKED","METHOD_NOT_ALLOWED","TARGET_UNREACHABLE","NO_PAYMENT_CHALLENGE","NETWORK_NOT_SUPPORTED","ASSET_NOT_SUPPORTED","PRICE_OVER_BUDGET"],"description":"Why a target is not eligible for a release test.","isRequired":true,"uniqueKey":"reason","typeLabel":"enum\u003cstring>"},"message":{"type":"string","isRequired":true,"uniqueKey":"message","typeLabel":"string"}},"uniqueKey":"","typeLabel":"object"},"examples":{"AUTHORIZATION_MISSING":{"title":"AUTHORIZATION_MISSING","value":{"eligible":false,"preflightId":"pfl_…","reason":"AUTHORIZATION_MISSING","message":"No verified authorization covers this target origin, route and method"}},"AUTHORIZATION_EXPIRED":{"title":"AUTHORIZATION_EXPIRED","value":{"eligible":false,"preflightId":"pfl_…","reason":"AUTHORIZATION_EXPIRED","message":"The authorization is not verified or has expired; verify it again"}}},"exampleType":"examples"}},"exampleType":"examples"},"e69c6907-9815-4f0a-9bb3-f09ba9ab9ede":{"description":"The request body is larger than 64 KiB (65536 bytes).","content":{"application/json":{"schema":{"type":"object","description":"Error body returned by every failing request.","required":["error","message"],"properties":{"error":{"type":"string","description":"Stable machine-readable error code, for example `VALIDATION_FAILED`.","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"message":{"type":"string","description":"Human-readable explanation. Do not parse it.","isRequired":true,"uniqueKey":"message","typeLabel":"string"}},"uniqueKey":"","typeLabel":"object"},"examples":{"PAYLOAD_TOO_LARGE":{"title":"PAYLOAD_TOO_LARGE","value":{"error":"PAYLOAD_TOO_LARGE","message":"Request body exceeds 65536 bytes"}}},"exampleType":"examples"}},"exampleType":"examples"},"7a0b6248-8426-4d2a-b733-80c7ab55c40c":{"description":"The target cannot be tested. Probe rejections carry a stored `preflightId`; a blocked hostname found while parsing the URL has `preflightId: null`.","content":{"application/json":{"schema":{"type":"object","description":"The target cannot be tested. Nothing was paid.","required":["eligible","preflightId","reason","message"],"properties":{"eligible":{"type":"boolean","const":false,"isRequired":true,"uniqueKey":"eligible","typeLabel":"boolean"},"preflightId":{"oneOf":[{"type":"string","description":"ID of the stored preflight, or `null` when Selo refused the request before storing it (invalid URL, blocked hostname, unknown authorization).","isRequired":true,"uniqueKey":"preflightId.oneOf.0","typeLabel":"string"},{"type":"null","description":"ID of the stored preflight, or `null` when Selo refused the request before storing it (invalid URL, blocked hostname, unknown authorization).","isRequired":true,"uniqueKey":"preflightId.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"preflightId","typeLabel":"string | null"},"reason":{"type":"string","enum":["AUTHORIZATION_MISSING","AUTHORIZATION_EXPIRED","TARGET_URL_INVALID","TARGET_NOT_HTTPS","TARGET_ADDRESS_BLOCKED","METHOD_NOT_ALLOWED","TARGET_UNREACHABLE","NO_PAYMENT_CHALLENGE","NETWORK_NOT_SUPPORTED","ASSET_NOT_SUPPORTED","PRICE_OVER_BUDGET"],"description":"Why a target is not eligible for a release test.","isRequired":true,"uniqueKey":"reason","typeLabel":"enum\u003cstring>"},"message":{"type":"string","isRequired":true,"uniqueKey":"message","typeLabel":"string"}},"uniqueKey":"","typeLabel":"object"},"examples":{"TARGET_ADDRESS_BLOCKED":{"title":"TARGET_ADDRESS_BLOCKED","value":{"eligible":false,"preflightId":"pfl_…","reason":"TARGET_ADDRESS_BLOCKED","message":"The target must be a public hostname on the default https port"}},"TARGET_UNREACHABLE":{"title":"TARGET_UNREACHABLE","value":{"eligible":false,"preflightId":"pfl_…","reason":"TARGET_UNREACHABLE","message":"The target could not be reached or answered with a server error"}},"NO_PAYMENT_CHALLENGE":{"title":"NO_PAYMENT_CHALLENGE","value":{"eligible":false,"preflightId":"pfl_…","reason":"NO_PAYMENT_CHALLENGE","message":"The target did not answer the unpaid request with a valid x402 challenge"}},"NETWORK_NOT_SUPPORTED":{"title":"NETWORK_NOT_SUPPORTED","value":{"eligible":false,"preflightId":"pfl_…","reason":"NETWORK_NOT_SUPPORTED","message":"The target offers no exact payment on the Algorand network Selo pays on"}},"ASSET_NOT_SUPPORTED":{"title":"ASSET_NOT_SUPPORTED","value":{"eligible":false,"preflightId":"pfl_…","reason":"ASSET_NOT_SUPPORTED","message":"The target offers no exact payment in USDC on the Algorand network"}},"PRICE_OVER_BUDGET":{"title":"PRICE_OVER_BUDGET","value":{"eligible":false,"preflightId":"pfl_…","reason":"PRICE_OVER_BUDGET","message":"The target price exceeds the per-job downstream spend limit"}}},"exampleType":"examples"}},"exampleType":"examples"},"93a27636-f957-4bd4-8e25-b9cde0b497e4":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"type":"object","description":"Error body returned by every failing request.","required":["error","message"],"properties":{"error":{"type":"string","description":"Stable machine-readable error code, for example `VALIDATION_FAILED`.","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"message":{"type":"string","description":"Human-readable explanation. Do not parse it.","isRequired":true,"uniqueKey":"message","typeLabel":"string"}},"uniqueKey":"","typeLabel":"object"},"examples":{"INTERNAL":{"title":"INTERNAL","value":{"error":"INTERNAL","message":"Internal server error"}}},"exampleType":"examples"}},"exampleType":"examples"}},"security":{},"servers":{"fbe7f743-573d-4126-9bae-6b7b65ed90a1":{"url":"https://api.useselo.xyz","description":"Production, Algorand Mainnet"}}},"originalFileLocation":"openapi.json"},"subdomain":"selo","siteName":"Selo","title":"Run a preflight - Selo","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-26T20:23:38.207Z","originalFileLocation":"api-reference/preflight/run-a-preflight.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Check, for free, that a target can be tested before you pay. Selo checks the authorization, sends one unpaid request to the target (with requestBody for POST, 10 second timeout, redirects not followed), reads its x402 v2 challenge, and requires an exact USDC payment on Algorand priced at or below the per-job spend limit (0.50 USDC). It also looks the target up in the Bazaar catalog and stores what it finds with the preflight. An eligible preflight is valid for 15 minutes.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Selo\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/selo/YPlIrdVM6zaS6GtN/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/selo/YPlIrdVM6zaS6GtN/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/selo/YPlIrdVM6zaS6GtN/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/selo/YPlIrdVM6zaS6GtN/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/selo/YPlIrdVM6zaS6GtN/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/selo/YPlIrdVM6zaS6GtN/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/selo/YPlIrdVM6zaS6GtN/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/selo/YPlIrdVM6zaS6GtN/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/selo/YPlIrdVM6zaS6GtN/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Run a preflight - Selo\">\u003cmeta data-mint-head property=\"og:description\" content=\"Check, for free, that a target can be tested before you pay. Selo checks the authorization, sends one unpaid request to the target (with requestBody for POST, 10 second timeout, redirects not followed), reads its x402 v2 challenge, and requires an exact USDC payment on Algorand priced at or below the per-job spend limit (0.50 USDC). It also looks the target up in the Bazaar catalog and stores what it finds with the preflight. An eligible preflight is valid for 15 minutes.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Selo docs\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.useselo.xyz/api-reference/preflight/run-a-preflight\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://selo.mintlify.app/_mintlify/api/og/v2?division=Endpoints\u0026amp;title=Run+a+preflight\u0026amp;description=Check%2C+for+free%2C+that+a+target+can+be+tested+before+you+pay.+Selo+checks+the+authorization%2C+sends+one+unpaid+request+to+the+target+%28with+%60requestBody%60+for+%60POST\u0026amp;theme=ae71d371ce055a9e660ed9fc\u0026amp;signature=5ec713db1b8d215c2c406510bdb3b84c5c2f5e3c276d30f5b23ff45b0570ab09\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Run a preflight - Selo\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Check, for free, that a target can be tested before you pay. Selo checks the authorization, sends one unpaid request to the target (with requestBody for POST, 10 second timeout, redirects not followed), reads its x402 v2 challenge, and requires an exact USDC payment on Algorand priced at or below the per-job spend limit (0.50 USDC). It also looks the target up in the Bazaar catalog and stores what it finds with the preflight. An eligible preflight is valid for 15 minutes.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://selo.mintlify.app/_mintlify/api/og/v2?division=Endpoints\u0026amp;title=Run+a+preflight\u0026amp;description=Check%2C+for+free%2C+that+a+target+can+be+tested+before+you+pay.+Selo+checks+the+authorization%2C+sends+one+unpaid+request+to+the+target+%28with+%60requestBody%60+for+%60POST\u0026amp;theme=ae71d371ce055a9e660ed9fc\u0026amp;signature=5ec713db1b8d215c2c406510bdb3b84c5c2f5e3c276d30f5b23ff45b0570ab09\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/selo/YPlIrdVM6zaS6GtN/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Selo\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#EA580C\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.useselo.xyz/api-reference/preflight/run-a-preflight\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/api-reference/preflight/run-a-preflight.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.useselo.xyz/#organization\",\"name\":\"Selo\",\"url\":\"https://docs.useselo.xyz\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/selo/uDDPP6e9J3oqq-so/logo/light.svg?fit=max\u0026auto=format\u0026n=uDDPP6e9J3oqq-so\u0026q=85\u0026s=34ba3a87bcb123757ba48be31d19069d\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.useselo.xyz#website\",\"name\":\"Selo\",\"url\":\"https://docs.useselo.xyz\",\"publisher\":{\"@id\":\"https://docs.useselo.xyz/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.useselo.xyz/api-reference/preflight/run-a-preflight#webpage\",\"url\":\"https://docs.useselo.xyz/api-reference/preflight/run-a-preflight\",\"name\":\"Run a preflight\",\"description\":\"Check, for free, that a target can be tested before you pay. Selo checks the authorization, sends one unpaid request to the target (with requestBody for POST, 10 second timeout, redirects not followed), reads its x402 v2 challenge, and requires an exact USDC payment on Algorand priced at or below the per-job spend limit (0.50 USDC). It also looks the target up in the Bazaar catalog and stores what it finds with the preflight. An eligible preflight is valid for 15 minutes.\",\"dateModified\":\"2026-10-26T20:23:38.207Z\",\"isPartOf\":{\"@id\":\"https://docs.useselo.xyz#website\"},\"breadcrumb\":{\"@id\":\"https://docs.useselo.xyz/api-reference/preflight/run-a-preflight#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.useselo.xyz/api-reference/preflight/run-a-preflight#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Endpoints\",\"item\":\"https://docs.useselo.xyz/api-reference/authorizations/create-an-authorization\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Run a preflight\",\"item\":\"https://docs.useselo.xyz/api-reference/preflight/run-a-preflight\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://docs.useselo.xyz/api-reference/preflight/run-a-preflight#apireference\",\"headline\":\"Run a preflight\",\"name\":\"Run a preflight\",\"description\":\"Check, for free, that a target can be tested before you pay. Selo checks the authorization, sends one unpaid request to the target (with requestBody for POST, 10 second timeout, redirects not followed), reads its x402 v2 challenge, and requires an exact USDC payment on Algorand priced at or below the per-job spend limit (0.50 USDC). It also looks the target up in the Bazaar catalog and stores what it finds with the preflight. An eligible preflight is valid for 15 minutes.\",\"url\":\"https://docs.useselo.xyz/api-reference/preflight/run-a-preflight\",\"mainEntityOfPage\":{\"@id\":\"https://docs.useselo.xyz/api-reference/preflight/run-a-preflight#webpage\"},\"dateModified\":\"2026-10-26T20:23:38.207Z\",\"publisher\":{\"@id\":\"https://docs.useselo.xyz/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.useselo.xyz#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Selo\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Selo","nav":{"global":{"anchors":[{"anchor":"Website","icon":"globe","href":"https://useselo.xyz"},{"anchor":"GitHub","icon":"github","href":"https://github.com/Enoch208/selo"},{"anchor":"Pilot guide","icon":"flag-checkered","href":"https://github.com/Enoch208/selo/blob/main/docs/PILOT_GUIDE.md"}]},"tabs":[{"tab":"Documentation","icon":"book-open","pages":[{"title":"Documentation","href":""}]},{"tab":"CLI reference","icon":"terminal","pages":[{"title":"CLI reference","href":"/cli/overview"}]},{"tab":"API reference","icon":"code","groups":[{"group":"Overview","pages":[{"title":"API overview","icon":"code","sidebarTitle":"Overview","href":"/api-reference/introduction"},{"title":"Errors and reason codes","icon":"triangle-exclamation","sidebarTitle":"Errors and reasons","href":"/api-reference/errors"},{"title":"Objects","icon":"brackets-curly","sidebarTitle":"Objects","href":"/api-reference/objects"}]},{"group":"Endpoints","pages":[{"title":"Create an authorization","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/authorizations","href":"/api-reference/authorizations/create-an-authorization"},{"title":"Verify an authorization","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/authorizations/{authorizationId}/verify","href":"/api-reference/authorizations/verify-an-authorization"},{"title":"Get an authorization","description":"Read the current state of an authorization. A `PENDING` or `VERIFIED` authorization past `expiresAt` is moved to `EXPIRED` by this read.","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/authorizations/{authorizationId}","href":"/api-reference/authorizations/get-an-authorization"},{"title":"Run a preflight","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/preflight","href":"/api-reference/preflight/run-a-preflight"},{"title":"Get a preflight","description":"Read a stored preflight, eligible or not, with status 200. The response is not re-evaluated: compare `expiresAt` with the current time before paying.","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/preflight/{preflightId}","href":"/api-reference/preflight/get-a-preflight"},{"title":"Run a release test","deprecated":null,"version":null,"openapi":"/openapi.json post /v1/release-test","href":"/api-reference/release-tests/run-a-release-test"},{"title":"Get a private report","deprecated":null,"version":null,"openapi":"/openapi.json get /v1/reports/{token}","href":"/api-reference/reports/get-a-private-report"},{"title":"Get attestation keys","deprecated":null,"version":null,"openapi":"/openapi.json get /.well-known/selo-attestation-keys.json","href":"/api-reference/attestation-keys/get-attestation-keys"},{"title":"Get llms.txt","deprecated":null,"version":null,"openapi":"/openapi.json get /llms.txt","href":"/api-reference/discovery/get-llmstxt"},{"title":"Get the agent card","deprecated":null,"version":null,"openapi":"/openapi.json get /.well-known/agent-card.json","href":"/api-reference/discovery/get-the-agent-card"},{"title":"Check health","deprecated":null,"version":null,"openapi":"/openapi.json get /health","href":"/api-reference/health/check-health"}]}]}]},"title":"Run a preflight - Selo","buildId":"dpl_DFJrtvUi8HS5F9nkooKuDJsuD5BM","deploymentId":"dpl_DFJrtvUi8HS5F9nkooKuDJsuD5BM","dynamics":["c2aa737661","2b790eda92","b0f84f53ff","a9bb46feb3"],"chunks":["OpenApiReferenceProvider-rfhihCWU.js","utils-BmH1XFxk.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-BcNsxPKB.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-BAES3tkd.js","snippetPresets-DCMQBKLP.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","ApiExamples-D6l_bzE9.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-BOktbnNh.js","shallow-BCs8SgM7.js","getApiPlaygroundDisplay-DEmW5bJB.js","CodeSnippet-CpZOpB9C.js","CodeSnippets-BOBDqibl.js","Page-D5fEM6aW.js","getPastedJson-DH2JBvmr.js","icon-BBJH-kKh.js","MethodPill-D2Sd5NLC.js","DuplicateIcon-CGgfL2qN.js","createIcon-BKudBBzi.js","DynamicMarkdown-85clUA0i.js","SectionHeading-D0JiMgDx.js","axios-vUo_bRtp.js","Markdown-Cfiy0xZO.js","clsx-rL8ZCCw4.js","lib--scc4DXi.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-aeztFa9U.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink-BywkCr5C.js"]}