{"openapi":"3.1.0","info":{"title":"Unbyte API","version":"1.0","summary":"Decode Solana transactions and programs, and verify a transaction before signing it.","description":"Every error answers the same envelope with a fixed code and message. A 429 or 503 carries `Retry-After`. Successful /v1 data responses name the registry they were decoded with in `Unbyte-Registry-Version`."},"externalDocs":{"url":"https://unbyte.dev/docs"},"servers":[{"url":"https://api.unbyte.dev"}],"security":[{},{"apiKey":[]}],"tags":[{"name":"decode","description":"Transactions and programs, decoded."},{"name":"verify","description":"Check an unsigned transaction against what the signer intends."},{"name":"account","description":"The signed-in account and its API keys (dashboard session, not API keys)."}],"paths":{"/v1/health":{"get":{"operationId":"health","summary":"Service health and the loaded registry","responses":{"200":{"description":"Healthy.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}},"429":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"}}}},"/v1/tx/{sig}":{"get":{"operationId":"getTransaction","tags":["decode"],"summary":"Decode a confirmed transaction by signature","description":"A finalized transaction is immutable and carries an `ETag`; revalidating with `If-None-Match` answers 304 without reading the chain. A transaction too recent to be final answers `Cache-Control: public, max-age=10` and no `ETag`.","parameters":[{"name":"sig","in":"path","required":true,"description":"The base58 64-byte signature.","schema":{"type":"string","pattern":"^[1-9A-HJ-NP-Za-km-z]+$","maxLength":88}},{"name":"raw","in":"query","required":false,"description":"`1` or `true` keeps the raw instruction data.","schema":{"type":"string"}},{"name":"If-None-Match","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"The decoded transaction.","headers":{"ETag":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransactionReport"}}}},"304":{"description":"The client's copy is current (`If-None-Match` matched)."},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"502":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"504":{"$ref":"#/components/responses/Error"}}}},"/v1/decode/tx":{"post":{"operationId":"decodeTransaction","tags":["decode"],"summary":"Decode a serialized transaction","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecodeTxRequest"}}}},"responses":{"200":{"description":"The decoded transaction.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransactionReport"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"411":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"502":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"504":{"$ref":"#/components/responses/Error"}}}},"/v1/verify":{"post":{"operationId":"verify","tags":["verify"],"summary":"Verify an unsigned transaction before signing","description":"Checks the transaction's instructions and balance effects against the intent. It does not simulate.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyRequest"}}}},"responses":{"200":{"description":"The verdict and its findings.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyReport"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"411":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"502":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"504":{"$ref":"#/components/responses/Error"}}}},"/v1/programs/{id}":{"get":{"operationId":"describeProgram","tags":["decode"],"summary":"Describe a program: name, category, IDL source and activity","parameters":[{"name":"id","in":"path","required":true,"description":"The program address.","schema":{"type":"string","pattern":"^[1-9A-HJ-NP-Za-km-z]+$","minLength":32,"maxLength":44,"description":"A base58 32-byte address."}}],"responses":{"200":{"description":"The program.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Program"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"}}}},"/v1/programs/{id}/idl":{"get":{"operationId":"getProgramIdl","tags":["decode"],"summary":"The program's IDL: the registry's as published, else the normalized on-chain IDL","parameters":[{"name":"id","in":"path","required":true,"description":"The program address.","schema":{"type":"string","pattern":"^[1-9A-HJ-NP-Za-km-z]+$","minLength":32,"maxLength":44,"description":"A base58 32-byte address."}},{"name":"If-None-Match","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"The IDL.","headers":{"ETag":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object"}}}},"304":{"description":"The client's copy is current (`If-None-Match` matched)."},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"502":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"504":{"$ref":"#/components/responses/Error"}}}},"/v1/me":{"get":{"operationId":"me","tags":["account"],"summary":"The signed-in account, its wallets, plan limits and this month's usage","security":[{"session":[]}],"responses":{"200":{"description":"The account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"401":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"}}}},"/v1/keys":{"get":{"operationId":"listKeys","tags":["account"],"summary":"Every API key of the account, revoked ones included","security":[{"session":[]}],"responses":{"200":{"description":"The keys.","content":{"application/json":{"schema":{"type":"object","required":["keys"],"properties":{"keys":{"type":"array","items":{"$ref":"#/components/schemas/Key"}}}}}}},"401":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"}}},"post":{"operationId":"createKey","tags":["account"],"summary":"Create an API key (returned once)","security":[{"session":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateKeyRequest"}}}},"responses":{"201":{"description":"The new key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewKey"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"411":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"}}}},"/v1/keys/{id}/rotate":{"post":{"operationId":"rotateKey","tags":["account"],"summary":"Replace a key: a new key (returned once) and the old one revoked","security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^key_[a-z2-7]{24}$"}}],"responses":{"201":{"description":"The replacement key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RotatedKey"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"411":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"}}}},"/v1/keys/{id}":{"delete":{"operationId":"revokeKey","tags":["account"],"summary":"Revoke a key; it stops working everywhere within 60 s","security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^key_[a-z2-7]{24}$"}}],"responses":{"200":{"description":"Revoked.","content":{"application/json":{"schema":{"type":"object","required":["id","revoked"],"properties":{"id":{"type":"string","pattern":"^key_[a-z2-7]{24}$"},"revoked":{"const":true}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"}}}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"An API key: `Authorization: Bearer ub_live_<32 base58 characters>`."},"session":{"type":"apiKey","in":"cookie","name":"__Host-unbyte.session_token","description":"The dashboard's wallet sign-in session. Requests other than GET also need an allowed `Origin` and an `X-Requested-With` header; API keys are not accepted here."}},"responses":{"Error":{"description":"The error envelope: a fixed code and message, never the input.","headers":{"Retry-After":{"description":"Seconds to wait; sent with 429 and 503.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","required":["error"],"additionalProperties":false,"properties":{"error":{"type":"object","required":["code","message"],"additionalProperties":false,"properties":{"code":{"type":"string","description":"Stable machine-readable code, e.g. `invalid_request`, `rate_limited`, `not_found`."},"message":{"type":"string","description":"The code's fixed human-readable message."}}}}},"Health":{"type":"object","required":["ok","registry_version","idls_loaded","rpc"],"properties":{"ok":{"const":true},"registry_version":{"type":"string"},"idls_loaded":{"type":"integer"},"rpc":{"type":"object","required":["mode"],"properties":{"mode":{"enum":["normal","cache_only"]}}}}},"LoadedAddresses":{"type":"object","required":["writable","readonly"],"additionalProperties":false,"properties":{"writable":{"type":"array","maxItems":256,"items":{"type":"string","pattern":"^[1-9A-HJ-NP-Za-km-z]+$","minLength":32,"maxLength":44,"description":"A base58 32-byte address."}},"readonly":{"type":"array","maxItems":256,"items":{"type":"string","pattern":"^[1-9A-HJ-NP-Za-km-z]+$","minLength":32,"maxLength":44,"description":"A base58 32-byte address."}}}},"DecodeTxRequest":{"type":"object","required":["transaction"],"additionalProperties":false,"properties":{"transaction":{"type":"string","maxLength":5594,"description":"The serialized transaction, base64 or base58."},"slot":{"type":"integer","minimum":0,"maximum":9007199254740991},"loaded_addresses":{"$ref":"#/components/schemas/LoadedAddresses"},"raw":{"type":"boolean","description":"Keep the raw instruction data."}}},"Intent":{"type":"object","additionalProperties":false,"properties":{"max_in":{"type":"string","pattern":"^(0|[1-9][0-9]{0,19})$","description":"An unsigned 64-bit integer as a decimal string."},"in_mint":{"anyOf":[{"const":"SOL"},{"type":"string","pattern":"^[1-9A-HJ-NP-Za-km-z]+$","minLength":32,"maxLength":44,"description":"A base58 32-byte address."}]},"min_out":{"type":"string","pattern":"^(0|[1-9][0-9]{0,19})$","description":"An unsigned 64-bit integer as a decimal string."},"out_mint":{"anyOf":[{"const":"SOL"},{"type":"string","pattern":"^[1-9A-HJ-NP-Za-km-z]+$","minLength":32,"maxLength":44,"description":"A base58 32-byte address."}]},"max_slippage_bps":{"type":"integer","minimum":0,"maximum":10000},"allow_programs":{"type":"array","maxItems":64,"items":{"type":"string","pattern":"^[1-9A-HJ-NP-Za-km-z]+$","minLength":32,"maxLength":44,"description":"A base58 32-byte address."}},"signer":{"type":"string","pattern":"^[1-9A-HJ-NP-Za-km-z]+$","minLength":32,"maxLength":44,"description":"A base58 32-byte address."}}},"VerifyRequest":{"type":"object","required":["transaction"],"additionalProperties":false,"properties":{"transaction":{"type":"string","maxLength":5594,"description":"The unsigned serialized transaction, base64 or base58."},"intent":{"$ref":"#/components/schemas/Intent"},"resolve_lookups":{"type":"boolean","description":"Resolve address lookup tables from the chain."}}},"Instruction":{"type":"object","required":["position","program_id","status"],"properties":{"position":{"type":"array","items":{"type":"integer"},"description":"Index path: top-level instruction, then inner ones."},"program_id":{"type":"string","pattern":"^[1-9A-HJ-NP-Za-km-z]+$","minLength":32,"maxLength":44,"description":"A base58 32-byte address."},"status":{"type":"string","description":"e.g. `decoded`, `no_idl`, `idl_unusable`, `error`, `event`."},"name":{"type":"string"},"account_keys":{"type":"array","items":{"type":"string"}},"data":{}}},"TransactionReport":{"type":"object","required":["instructions","registry_version"],"properties":{"signature":{"type":"string"},"slot":{"type":"integer"},"failed":{"type":"boolean"},"fee_payer":{"type":"string","pattern":"^[1-9A-HJ-NP-Za-km-z]+$","minLength":32,"maxLength":44,"description":"A base58 32-byte address."},"instructions":{"type":"array","items":{"$ref":"#/components/schemas/Instruction"}},"balance_changes":{"type":"array","items":{"type":"object"}},"log_events":{"type":"array","items":{"type":"object"}},"registry_version":{"type":"string"}}},"VerifyReport":{"type":"object","required":["verdict","findings"],"properties":{"verdict":{"enum":["ok","warn","block"]},"findings":{"type":"array","items":{"type":"object","required":["code","severity"],"properties":{"code":{"type":"string"},"severity":{"type":"string"}}}},"disclaimer":{"type":"string"}}},"Program":{"type":"object","required":["program_id","registry_version"],"properties":{"program_id":{"type":"string","pattern":"^[1-9A-HJ-NP-Za-km-z]+$","minLength":32,"maxLength":44,"description":"A base58 32-byte address."},"name":{"type":["string","null"]},"name_inferred":{"type":"boolean"},"category":{"type":"string"},"kind":{"type":["string","null"]},"idl":{"type":"object","properties":{"source":{"enum":["registry","chain","none"]},"fingerprint":{"type":["string","null"]},"version":{"type":["string","null"]}}},"health":{},"activity":{"type":["object","null"]},"swap":{},"meanings":{"type":"object","additionalProperties":{"type":"string"}},"note":{"type":["string","null"]},"registry_version":{"type":"string"}}},"Account":{"type":"object","required":["user","wallets","limits","usage"],"properties":{"user":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":["string","null"]},"plan":{"type":"string"},"plan_until":{"type":["integer","null"]},"credits_micro":{"type":"integer","description":"Prepaid credit in micro-USD."},"created_at":{"type":"integer","description":"Unix time in milliseconds."}}},"wallets":{"type":"array","items":{"type":"object","properties":{"chain":{"type":"string"},"address":{"type":"string"},"is_owner":{"type":"boolean"},"linked_at":{"type":"integer","description":"Unix time in milliseconds."}}}},"limits":{"type":"object"},"usage":{"type":"object"}}},"Scopes":{"type":"array","items":{"enum":["decode","verify","idl"]},"minItems":1,"uniqueItems":true},"Key":{"type":"object","properties":{"id":{"type":"string","pattern":"^key_[a-z2-7]{24}$"},"prefix":{"type":"string","description":"The 8 characters after `ub_live_`."},"name":{"type":"string"},"scopes":{"$ref":"#/components/schemas/Scopes"},"expires_at":{"type":["integer","null"]},"last_used_at":{"type":["integer","null"]},"revoked_at":{"type":["integer","null"]},"created_at":{"type":"integer","description":"Unix time in milliseconds."}}},"CreateKeyRequest":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","maxLength":64,"pattern":"^[\\w .-]*$"},"scopes":{"$ref":"#/components/schemas/Scopes","description":"Default: every scope."},"expires_at":{"type":"integer","description":"Unix time in milliseconds, at most two years ahead."}}},"NewKey":{"type":"object","required":["key","id"],"properties":{"key":{"type":"string","description":"The key itself; shown only in this response."},"id":{"type":"string","pattern":"^key_[a-z2-7]{24}$"},"prefix":{"type":"string"},"name":{"type":"string"},"scopes":{"$ref":"#/components/schemas/Scopes"},"expires_at":{"type":["integer","null"]},"created_at":{"type":"integer","description":"Unix time in milliseconds."}}},"RotatedKey":{"type":"object","required":["key","id","replaces"],"properties":{"key":{"type":"string","description":"The new key; shown only in this response."},"id":{"type":"string","pattern":"^key_[a-z2-7]{24}$"},"prefix":{"type":"string"},"created_at":{"type":"integer","description":"Unix time in milliseconds."},"replaces":{"type":"object","properties":{"id":{"type":"string","pattern":"^key_[a-z2-7]{24}$"},"revoked_at":{"type":"integer","description":"Unix time in milliseconds."}}}}}}}}