Docs
Accounts and organisations
The t4 band (S5.5): sign-up and sign-in by password, link or passkey, the second factor and the step-up, the account's own data, organisations with members, invitations and API keys. Never an MCP tool; 501 not_configured while accounts are off.
Generated from openapi.yaml (Btcintel native API 0.1.0). Every hash is canonical display order; every answer carries the index and node heights; errors use one envelope — see Semantics.
- POST
/v1/auth/signup— Create an account with an e-mail address and a password - POST
/v1/auth/verify— Finish a sign-up with the link's token - POST
/v1/auth/password— Sign in with an e-mail address and a password - PUT
/v1/auth/password— Set a new password - POST
/v1/auth/link— Ask for a one-time sign-in link - POST
/v1/auth/link/verify— Sign in with the link's token - POST
/v1/auth/reset— Ask for a password-reset link - POST
/v1/auth/reset/verify— Open the reset link's session - PATCH
/v1/auth/account— Change the display name or the e-mail address - DELETE
/v1/auth/account— Close the account - POST
/v1/auth/email/verify— Confirm a new e-mail address with the link's token - GET
/v1/auth/export— The account's data as one JSON document - POST
/v1/auth/totp/enrol— Start enrolling an authenticator app - POST
/v1/auth/totp/verify— Confirm the app with its current code - POST
/v1/auth/totp/disable— Remove the authenticator app - POST
/v1/auth/recovery-codes— Regenerate the recovery codes - POST
/v1/auth/step-up— Lift this session to aal 2 for ten minutes - GET
/v1/orgs— The caller's organisations - POST
/v1/orgs— Create an organisation - POST
/v1/orgs/invites/accept— Join an organisation with an invitation's token - GET
/v1/orgs/{id}— An organisation and its members - PATCH
/v1/orgs/{id}/members/{account_id}— Change a member's role - DELETE
/v1/orgs/{id}/members/{account_id}— Remove a member, or leave - GET
/v1/orgs/{id}/invites— The open invitations - POST
/v1/orgs/{id}/invites— Invite an address - GET
/v1/orgs/{id}/audit— The organisation's audit rows - GET
/v1/orgs/{id}/keys— The organisation's keys - POST
/v1/orgs/{id}/keys— Issue a key owned by the organisation - DELETE
/v1/orgs/{id}/keys/{key_id}— Revoke a key of the organisation - GET
/v1/auth/keys— The account's keys - POST
/v1/auth/keys— Issue a key owned by the account - DELETE
/v1/auth/keys/{key_id}— Revoke a key of the account - GET
/v1/auth/webauthn— The account's passkeys - POST
/v1/auth/webauthn/register/begin— Start registering a passkey - POST
/v1/auth/webauthn/register/finish— Finish registering a passkey - POST
/v1/auth/webauthn/authenticate/begin— Start a passkey sign-in or step-up - POST
/v1/auth/webauthn/authenticate/finish— Finish a passkey sign-in or step-up - DELETE
/v1/auth/webauthn/{id}— Remove a passkey
POST /v1/auth/signup
Create an account with an e-mail address and a password
Spec S5.5 FR-1 (P55, P57). Answers 202 whether or not the address has an account: a new address receives a verification link that creates the account (POST /v1/auth/verify), an existing one a sign-in link instead. The password has 12 to 128 characters and no composition rules; one found in a known breach is refused with the reason (a k-anonymity range query, five hex characters of its SHA-1). A body carrying a private key (nsec1) is refused like any other. 501 while ACCOUNTS_ENABLED is off.
Request body
schema
emailstring required — Normalised to lower case; plus-addresses are kept.passwordstring required · min length 1 · max length 128
Response 202
Accepted; the answer does not say whether the address had an account.
schema
acceptedboolean requirednextstring — What to do now, in one sentence.
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X POST https://api.btcintel.io/v1/auth/signup \
-H 'Content-Type: application/json' \
-d '{"email":"…","password":"…"}' | jqPOST /v1/auth/verify
Finish a sign-up with the link's token
Spec S5.5 FR-1. The token from the verification e-mail, single use, 15 minutes: creates the account (t4, free) and opens its first session (aal 1, amr [link]). The cookie is the same btci_session a NIP-98 login sets.
Request body
schema
tokenstring required — The token from the e-mail link (URL-safe base64).
Response 201
The account and its session; the cookie is set.
schema
accountobject requiredidinteger (int64) requiredemailstringdisplay_namestringcreated_atstring (date-time) required
tierstring required · one of "t4"expires_atstring (date-time) requiredsession_idstring required — The row id (SHA-256 of the cookie token) as/v1/auth/melists it.aalinteger required · one of 1, 2amrarray of string requiredpassword_reset_onlybooleannextstring — Where the explorer lands after a provider link (POST /v1/auth/oauth/confirm): the path the flow started with.signing_identitySigningIdentity — The account's Nostr key when it has one; while custodied signing is on, a sign-in gives an account without one its custodied key first (spec S5.9 FR-1).pubkeystring required — 64 hex characters.npubstring requiredsourcestring required · one of "custodied", "nip07", "nip46", "nip55"linked_atstring (date-time) requiredexportableboolean required — True for a custodied key:POST /v1/auth/npub/exporthands it over.exported_atstring (date-time) — When a custodied key was last exported; absent until then, and while the signer does not answer.clientsarray of SignerClient — The NIP-46 apps connected to a custodied key (spec S5.6 FR-4); empty when none, absent while the signer does not answer.client_pubkeystring required — The app's pubkey, 64 hex characters.namestring required — What the account called the app when it made the link; may be empty.permsarray of string required — What the app may ask for:sign_event:<kind>,sign_event,nip44_encrypt,nip44_decrypt,nip04_encrypt,nip04_decrypt.connected_atstring (date-time) requiredlast_used_atstring (date-time) — Absent until the app's first request after connecting.
quotaQuotarequests_per_minintegerburst_per_minintegerrequests_per_dayintegerbulk_max_subjectsintegerpublish_per_dayintegerfeedback_per_dayinteger — Feedback entries per caller per UTC day (CC-8, spec S3.4).proposals_per_dayinteger — Curated proposals per caller per UTC day (CC-8, spec S5.1 FR-10).disputes_per_dayinteger — Disputes per caller per UTC day (CC-8, spec S5.3 FR-1).scopesarray of string
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).404— Unknown to the index and, for transactions, to the node mempool.501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X POST https://api.btcintel.io/v1/auth/verify \
-H 'Content-Type: application/json' \
-d '{"token":"…"}' | jqPOST /v1/auth/password
Sign in with an e-mail address and a password
Spec S5.5 FR-2. Argon2id; an unknown address takes the same time as a wrong password and gets the same 401; ten failures per account in fifteen minutes and thirty per client address in an hour answer 429 with Retry-After. The session opens at aal 1 with amr [password].
Request body
schema
emailstring required — Normalised to lower case; plus-addresses are kept.passwordstring required · min length 1 · max length 128
Response 201
The account and its session; the cookie is set.
schema
accountobject requiredidinteger (int64) requiredemailstringdisplay_namestringcreated_atstring (date-time) required
tierstring required · one of "t4"expires_atstring (date-time) requiredsession_idstring required — The row id (SHA-256 of the cookie token) as/v1/auth/melists it.aalinteger required · one of 1, 2amrarray of string requiredpassword_reset_onlybooleannextstring — Where the explorer lands after a provider link (POST /v1/auth/oauth/confirm): the path the flow started with.signing_identitySigningIdentity — The account's Nostr key when it has one; while custodied signing is on, a sign-in gives an account without one its custodied key first (spec S5.9 FR-1).pubkeystring required — 64 hex characters.npubstring requiredsourcestring required · one of "custodied", "nip07", "nip46", "nip55"linked_atstring (date-time) requiredexportableboolean required — True for a custodied key:POST /v1/auth/npub/exporthands it over.exported_atstring (date-time) — When a custodied key was last exported; absent until then, and while the signer does not answer.clientsarray of SignerClient — The NIP-46 apps connected to a custodied key (spec S5.6 FR-4); empty when none, absent while the signer does not answer.client_pubkeystring required — The app's pubkey, 64 hex characters.namestring required — What the account called the app when it made the link; may be empty.permsarray of string required — What the app may ask for:sign_event:<kind>,sign_event,nip44_encrypt,nip44_decrypt,nip04_encrypt,nip04_decrypt.connected_atstring (date-time) requiredlast_used_atstring (date-time) — Absent until the app's first request after connecting.
quotaQuotarequests_per_minintegerburst_per_minintegerrequests_per_dayintegerbulk_max_subjectsintegerpublish_per_dayintegerfeedback_per_dayinteger — Feedback entries per caller per UTC day (CC-8, spec S3.4).proposals_per_dayinteger — Curated proposals per caller per UTC day (CC-8, spec S5.1 FR-10).disputes_per_dayinteger — Disputes per caller per UTC day (CC-8, spec S5.3 FR-1).scopesarray of string
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).401— Missing or invalid bearer (unauthorized).429—quota_exceeded(spec S3.1 FR-4): the caller's tier ran out of requests for the minute or the day.Retry-Aftersays when to try again; every rate-limited answer carriesX-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-ResetandX-RateLimit-Tier. While the deployment runs in log-only mode the decision is logged instead andX-RateLimit-Policy: log-onlyis set.501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X POST https://api.btcintel.io/v1/auth/password \
-H 'Content-Type: application/json' \
-d '{"email":"…","password":"…"}' | jqPUT /v1/auth/password
Set a new password
Spec S5.5 FR-3 and FR-7. A reset link's session, or a session at aal 2, sets the password (the same policy as sign-up); every other session of the account is revoked. A session at aal 1 that did not come from a reset link answers 403: enrol a second factor or use the reset link.
- Auth
- An operator credential as the bearer; every call is audited.
Request body
schema
passwordstring required · min length 12 · max length 128
Response 200
The password is set.
schema
password_setboolean requiredsessions_revokedinteger required — The other sessions of the account that were revoked.
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).401— Missing or invalid bearer (unauthorized).403— The operator lacks the role or kind the action needs, or is switched off (forbidden).501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X PUT https://api.btcintel.io/v1/auth/password \
-H 'Authorization: Bearer $BTCI_KEY' \
-H 'Content-Type: application/json' \
-d '{"password":"…"}' | jqAn operator credential: the ops bearer or a btci_ key with the ops:agent scope.
POST /v1/auth/link
Ask for a one-time sign-in link
Spec S5.5 FR-3. Answers 202 always; an address with an account receives a link that signs in once, for 15 minutes, in whichever browser posts its token to POST /v1/auth/link/verify. One link per address per minute, ten per hour; beyond that the answer stays 202 and nothing is sent.
Request body
schema
emailstring required
Response 202
Accepted; the answer does not say whether the address has an account.
schema
acceptedboolean requirednextstring — What to do now, in one sentence.
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X POST https://api.btcintel.io/v1/auth/link \
-H 'Content-Type: application/json' \
-d '{"email":"…"}' | jqPOST /v1/auth/link/verify
Sign in with the link's token
Spec S5.5 FR-3. Single use; opens a session at aal 1 with amr [link].
Request body
schema
tokenstring required — The token from the e-mail link (URL-safe base64).
Response 201
The account and its session; the cookie is set.
schema
accountobject requiredidinteger (int64) requiredemailstringdisplay_namestringcreated_atstring (date-time) required
tierstring required · one of "t4"expires_atstring (date-time) requiredsession_idstring required — The row id (SHA-256 of the cookie token) as/v1/auth/melists it.aalinteger required · one of 1, 2amrarray of string requiredpassword_reset_onlybooleannextstring — Where the explorer lands after a provider link (POST /v1/auth/oauth/confirm): the path the flow started with.signing_identitySigningIdentity — The account's Nostr key when it has one; while custodied signing is on, a sign-in gives an account without one its custodied key first (spec S5.9 FR-1).pubkeystring required — 64 hex characters.npubstring requiredsourcestring required · one of "custodied", "nip07", "nip46", "nip55"linked_atstring (date-time) requiredexportableboolean required — True for a custodied key:POST /v1/auth/npub/exporthands it over.exported_atstring (date-time) — When a custodied key was last exported; absent until then, and while the signer does not answer.clientsarray of SignerClient — The NIP-46 apps connected to a custodied key (spec S5.6 FR-4); empty when none, absent while the signer does not answer.client_pubkeystring required — The app's pubkey, 64 hex characters.namestring required — What the account called the app when it made the link; may be empty.permsarray of string required — What the app may ask for:sign_event:<kind>,sign_event,nip44_encrypt,nip44_decrypt,nip04_encrypt,nip04_decrypt.connected_atstring (date-time) requiredlast_used_atstring (date-time) — Absent until the app's first request after connecting.
quotaQuotarequests_per_minintegerburst_per_minintegerrequests_per_dayintegerbulk_max_subjectsintegerpublish_per_dayintegerfeedback_per_dayinteger — Feedback entries per caller per UTC day (CC-8, spec S3.4).proposals_per_dayinteger — Curated proposals per caller per UTC day (CC-8, spec S5.1 FR-10).disputes_per_dayinteger — Disputes per caller per UTC day (CC-8, spec S5.3 FR-1).scopesarray of string
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).404— Unknown to the index and, for transactions, to the node mempool.501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X POST https://api.btcintel.io/v1/auth/link/verify \
-H 'Content-Type: application/json' \
-d '{"token":"…"}' | jqPOST /v1/auth/reset
Ask for a password-reset link
Spec S5.5 FR-3 ("Forgot your password"). Answers 202 always; an address with an account receives a link whose session can only set a new password (PUT /v1/auth/password) until it does. The same rate as the sign-in link.
Request body
schema
emailstring required
Response 202
Accepted; the answer does not say whether the address has an account.
schema
acceptedboolean requirednextstring — What to do now, in one sentence.
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X POST https://api.btcintel.io/v1/auth/reset \
-H 'Content-Type: application/json' \
-d '{"email":"…"}' | jqPOST /v1/auth/reset/verify
Open the reset link's session
Spec S5.5 FR-3. Single use; the session carries password_reset_only: true and may only set a new password.
Request body
schema
tokenstring required — The token from the e-mail link (URL-safe base64).
Response 201
The account and its reset-only session; the cookie is set.
schema
accountobject requiredidinteger (int64) requiredemailstringdisplay_namestringcreated_atstring (date-time) required
tierstring required · one of "t4"expires_atstring (date-time) requiredsession_idstring required — The row id (SHA-256 of the cookie token) as/v1/auth/melists it.aalinteger required · one of 1, 2amrarray of string requiredpassword_reset_onlybooleannextstring — Where the explorer lands after a provider link (POST /v1/auth/oauth/confirm): the path the flow started with.signing_identitySigningIdentity — The account's Nostr key when it has one; while custodied signing is on, a sign-in gives an account without one its custodied key first (spec S5.9 FR-1).pubkeystring required — 64 hex characters.npubstring requiredsourcestring required · one of "custodied", "nip07", "nip46", "nip55"linked_atstring (date-time) requiredexportableboolean required — True for a custodied key:POST /v1/auth/npub/exporthands it over.exported_atstring (date-time) — When a custodied key was last exported; absent until then, and while the signer does not answer.clientsarray of SignerClient — The NIP-46 apps connected to a custodied key (spec S5.6 FR-4); empty when none, absent while the signer does not answer.client_pubkeystring required — The app's pubkey, 64 hex characters.namestring required — What the account called the app when it made the link; may be empty.permsarray of string required — What the app may ask for:sign_event:<kind>,sign_event,nip44_encrypt,nip44_decrypt,nip04_encrypt,nip04_decrypt.connected_atstring (date-time) requiredlast_used_atstring (date-time) — Absent until the app's first request after connecting.
quotaQuotarequests_per_minintegerburst_per_minintegerrequests_per_dayintegerbulk_max_subjectsintegerpublish_per_dayintegerfeedback_per_dayinteger — Feedback entries per caller per UTC day (CC-8, spec S3.4).proposals_per_dayinteger — Curated proposals per caller per UTC day (CC-8, spec S5.1 FR-10).disputes_per_dayinteger — Disputes per caller per UTC day (CC-8, spec S5.3 FR-1).scopesarray of string
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).404— Unknown to the index and, for transactions, to the node mempool.501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X POST https://api.btcintel.io/v1/auth/reset/verify \
-H 'Content-Type: application/json' \
-d '{"token":"…"}' | jqPATCH /v1/auth/account
Change the display name or the e-mail address
Spec S5.5 FR-10. display_name changes at once (empty clears it). A new email needs aal 2 and is verified by a link sent to the new address (POST /v1/auth/email/verify); the answer is 202 whether or not that address is free, and the old address is told once the change is made.
- Auth
- An operator credential as the bearer; every call is audited.
Request body
schema
display_namestring · max length 80emailstring
Response 200
The account after the change.
schema
accountAccountInfo requiredidinteger (int64) requiredemailstringdisplay_namestringcreated_atstring (date-time) required
Response 202
The e-mail change waits for the link sent to the new address.
schema
acceptedboolean requirednextstring — What to do now, in one sentence.
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).401— Missing or invalid bearer (unauthorized).403— The operator lacks the role or kind the action needs, or is switched off (forbidden).501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X PATCH https://api.btcintel.io/v1/auth/account \
-H 'Authorization: Bearer $BTCI_KEY' \
-H 'Content-Type: application/json' \
-d '{}' | jqAn operator credential: the ops bearer or a btci_ key with the ops:agent scope.
DELETE /v1/auth/account
Close the account
Spec S5.5 FR-10, aal 2. Sign-in is refused and every session revoked; for 30 days a sign-in reopens the account unchanged; after that it is anonymised (e-mail, name and credentials removed; the audit rows keep the id). The address is told by e-mail.
- Auth
- An operator credential as the bearer; every call is audited.
Response 200
Closed.
schema
closedboolean requiredgrace_untilstring (date-time) required
Errors
401— Missing or invalid bearer (unauthorized).403— The operator lacks the role or kind the action needs, or is switched off (forbidden).501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X DELETE https://api.btcintel.io/v1/auth/account \
-H 'Authorization: Bearer $BTCI_KEY' | jqAn operator credential: the ops bearer or a btci_ key with the ops:agent scope.
POST /v1/auth/email/verify
Confirm a new e-mail address with the link's token
Spec S5.5 FR-10. Single use; replaces the address and tells the old one. 409 when another account took the address meanwhile.
Request body
schema
tokenstring required — The token from the e-mail link (URL-safe base64).
Response 200
The account with its new address.
schema
accountAccountInfo requiredidinteger (int64) requiredemailstringdisplay_namestringcreated_atstring (date-time) required
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).404— Unknown to the index and, for transactions, to the node mempool.409— The state refuses the change (conflict): an open dispute by this caller exists already, or the dispute or claim is not open any more.501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X POST https://api.btcintel.io/v1/auth/email/verify \
-H 'Content-Type: application/json' \
-d '{"token":"…"}' | jqGET /v1/auth/export
The account's data as one JSON document
Spec S5.5 FR-10: the account, every session (live or revoked; hashes, never a User-Agent string) and the audit rows the account caused. Served as an attachment.
- Auth
- An operator credential as the bearer; every call is audited.
Response 200
The export.
schema
exported_atstring (date-time) requiredaccountAccountInfo requiredidinteger (int64) requiredemailstringdisplay_namestringcreated_atstring (date-time) required
sessionsarray of object requiredloginsarray of object — The sign-in providers bound to the account (spec S5.5 FR-13); empty when none.providerstring required · one of "google", "github", "apple", "oidc"subjectstring required — The provider's stable identifier.emailstring — The address the provider reported.verifiedboolean requiredcreated_atstring (date-time) required
auditarray of object required
Errors
401— Missing or invalid bearer (unauthorized).403— The operator lacks the role or kind the action needs, or is switched off (forbidden).501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s https://api.btcintel.io/v1/auth/export \
-H 'Authorization: Bearer $BTCI_KEY' | jqAn operator credential: the ops bearer or a btci_ key with the ops:agent scope.
POST /v1/auth/totp/enrol
Start enrolling an authenticator app
Spec S5.5 FR-6 (RFC 6238: SHA-1, six digits, 30 s). A fresh secret shown once, as base32 and as an otpauth URL for the QR; nothing is stored until POST /v1/auth/totp/verify proves the app holds it, within 10 minutes. The first factor may be enrolled at aal 1 from a session signed in within the last 15 minutes (CP4-3: enrolment lifts the session to aal 2), else 403 asking for a new sign-in; adding one to an account that has a factor needs aal 2 (FR-7). 409 while an app is enrolled.
- Auth
- An operator credential as the bearer; every call is audited.
Request body (optional)
schema
namestring — How the person calls the app (default: Authenticator app). · max length 80
Response 201
The pending secret.
schema
secretstring required — Base32, for an app without a camera.otpauth_urlstring requiredexpires_atstring (date-time) requirednextstring
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).401— Missing or invalid bearer (unauthorized).403— The operator lacks the role or kind the action needs, or is switched off (forbidden).409— The state refuses the change (conflict): an open dispute by this caller exists already, or the dispute or claim is not open any more.501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X POST https://api.btcintel.io/v1/auth/totp/enrol \
-H 'Authorization: Bearer $BTCI_KEY' \
-H 'Content-Type: application/json' \
-d '{}' | jqAn operator credential: the ops bearer or a btci_ key with the ops:agent scope.
POST /v1/auth/totp/verify
Confirm the app with its current code
Spec S5.5 FR-6. The factor is stored sealed under TOTP_KEY, ten recovery codes are shown once (each works once), and this session is lifted to aal 2 for ten minutes. Ten wrong codes per account per quarter hour answer 429.
- Auth
- An operator credential as the bearer; every call is audited.
Request body
schema
codestring required — Six digits; spaces are ignored.
Response 201
Enrolled.
schema
enrolledstring required · one of "totp"recovery_codesarray of string requiredaalinteger required · one of 2aal_untilstring (date-time) requirednextstring
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).401— Missing or invalid bearer (unauthorized).403— The operator lacks the role or kind the action needs, or is switched off (forbidden).404— Unknown to the index and, for transactions, to the node mempool.409— The state refuses the change (conflict): an open dispute by this caller exists already, or the dispute or claim is not open any more.429—quota_exceeded(spec S3.1 FR-4): the caller's tier ran out of requests for the minute or the day.Retry-Aftersays when to try again; every rate-limited answer carriesX-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-ResetandX-RateLimit-Tier. While the deployment runs in log-only mode the decision is logged instead andX-RateLimit-Policy: log-onlyis set.501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X POST https://api.btcintel.io/v1/auth/totp/verify \
-H 'Authorization: Bearer $BTCI_KEY' \
-H 'Content-Type: application/json' \
-d '{"code":"…"}' | jqAn operator credential: the ops bearer or a btci_ key with the ops:agent scope.
POST /v1/auth/totp/disable
Remove the authenticator app
Spec S5.5 FR-6, aal 2. The app and the recovery codes go. An organisation admin or a key manager cannot be left without a second factor (FR-8): 403 unless a passkey remains.
- Auth
- An operator credential as the bearer; every call is audited.
Response 200
Removed.
schema
disabledstring required · one of "totp"
Errors
401— Missing or invalid bearer (unauthorized).403— The operator lacks the role or kind the action needs, or is switched off (forbidden).404— Unknown to the index and, for transactions, to the node mempool.501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X POST https://api.btcintel.io/v1/auth/totp/disable \
-H 'Authorization: Bearer $BTCI_KEY' | jqAn operator credential: the ops bearer or a btci_ key with the ops:agent scope.
POST /v1/auth/recovery-codes
Regenerate the recovery codes
Spec S5.5 FR-6, aal 2. A new set of ten, shown once; the old set is void. 404 without a second factor.
- Auth
- An operator credential as the bearer; every call is audited.
Response 201
The new codes.
schema
recovery_codesarray of string required
Errors
401— Missing or invalid bearer (unauthorized).403— The operator lacks the role or kind the action needs, or is switched off (forbidden).404— Unknown to the index and, for transactions, to the node mempool.501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X POST https://api.btcintel.io/v1/auth/recovery-codes \
-H 'Authorization: Bearer $BTCI_KEY' | jqAn operator credential: the ops bearer or a btci_ key with the ops:agent scope.
POST /v1/auth/step-up
Lift this session to aal 2 for ten minutes
Spec S5.5 FR-7. code is the authenticator app's current code (a code is accepted once; one step of drift either way); recovery_code one of the codes shown at enrolment (used once). The routes that need aal 2 say so with 403 until then. Ten wrong codes per account per quarter hour answer 429.
- Auth
- An operator credential as the bearer; every call is audited.
Request body
schema
codestringrecovery_codestring
Response 200
Stepped up.
schema
aalinteger required · one of 2aal_untilstring (date-time) requiredmethodstring required · one of "totp", "recovery"recovery_codes_leftinteger
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).401— Missing or invalid bearer (unauthorized).403— The operator lacks the role or kind the action needs, or is switched off (forbidden).404— Unknown to the index and, for transactions, to the node mempool.429—quota_exceeded(spec S3.1 FR-4): the caller's tier ran out of requests for the minute or the day.Retry-Aftersays when to try again; every rate-limited answer carriesX-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-ResetandX-RateLimit-Tier. While the deployment runs in log-only mode the decision is logged instead andX-RateLimit-Policy: log-onlyis set.501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X POST https://api.btcintel.io/v1/auth/step-up \
-H 'Authorization: Bearer $BTCI_KEY' \
-H 'Content-Type: application/json' \
-d '{}' | jqAn operator credential: the ops bearer or a btci_ key with the ops:agent scope.
GET /v1/orgs
The caller's organisations
Spec S5.5 FR-11: every open organisation the account belongs to, with its role.
- Auth
- An operator credential as the bearer; every call is audited.
Response 200
The organisations.
schema
organisationsarray of Organisation requiredidinteger (int64) requirednamestring requiredslugstring requiredcreated_atstring (date-time) requiredrolestring — The caller's role. · one of "admin", "member", "billing"
Errors
401— Missing or invalid bearer (unauthorized).403— The operator lacks the role or kind the action needs, or is switched off (forbidden).501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s https://api.btcintel.io/v1/orgs \
-H 'Authorization: Bearer $BTCI_KEY' | jqAn operator credential: the ops bearer or a btci_ key with the ops:agent scope.
POST /v1/orgs
Create an organisation
Spec S5.5 FR-11 (P55), aal 2. The account's verified address must not be a personal provider's (access.free_email_domains; unknown domains are allowed) and the creator holds a second factor (FR-8). The creator is the first admin; the slug comes from the name.
- Auth
- An operator credential as the bearer; every call is audited.
Request body
schema
namestring required · min length 1 · max length 120
Response 201
The organisation and the creator's role.
schema
organisationOrganisation requiredidinteger (int64) requirednamestring requiredslugstring requiredcreated_atstring (date-time) requiredrolestring — The caller's role. · one of "admin", "member", "billing"
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).401— Missing or invalid bearer (unauthorized).403— The operator lacks the role or kind the action needs, or is switched off (forbidden).501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X POST https://api.btcintel.io/v1/orgs \
-H 'Authorization: Bearer $BTCI_KEY' \
-H 'Content-Type: application/json' \
-d '{"name":"…"}' | jqAn operator credential: the ops bearer or a btci_ key with the ops:agent scope.
POST /v1/orgs/invites/accept
Join an organisation with an invitation's token
Spec S5.5 FR-11. The signed-in account's address must be the invited one (403 otherwise; the invitation is not spent). Single use, seven days.
- Auth
- An operator credential as the bearer; every call is audited.
Request body
schema
tokenstring required — The token from the e-mail link (URL-safe base64).
Response 200
The organisation joined and the role.
schema
organisationOrganisation requiredidinteger (int64) requirednamestring requiredslugstring requiredcreated_atstring (date-time) requiredrolestring — The caller's role. · one of "admin", "member", "billing"
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).401— Missing or invalid bearer (unauthorized).403— The operator lacks the role or kind the action needs, or is switched off (forbidden).404— Unknown to the index and, for transactions, to the node mempool.501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X POST https://api.btcintel.io/v1/orgs/invites/accept \
-H 'Authorization: Bearer $BTCI_KEY' \
-H 'Content-Type: application/json' \
-d '{"token":"…"}' | jqAn operator credential: the ops bearer or a btci_ key with the ops:agent scope.
GET /v1/orgs/{id}
An organisation and its members
Spec S5.5 FR-11. Members see each other's display names; admins also see e-mail addresses. A stranger gets 404.
- Auth
- An operator credential as the bearer; every call is audited.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
id required | path | integer (int64) | — |
Response 200
The organisation and its members.
schema
organisationOrganisation requiredidinteger (int64) requirednamestring requiredslugstring requiredcreated_atstring (date-time) requiredrolestring — The caller's role. · one of "admin", "member", "billing"
membersarray of OrgMember requiredaccount_idinteger (int64) requiredrolestring required · one of "admin", "member", "billing"joined_atstring (date-time) requireddisplay_namestringemailstring — Admins only.
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).401— Missing or invalid bearer (unauthorized).403— The operator lacks the role or kind the action needs, or is switched off (forbidden).404— Unknown to the index and, for transactions, to the node mempool.501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s https://api.btcintel.io/v1/orgs/1 \
-H 'Authorization: Bearer $BTCI_KEY' | jqAn operator credential: the ops bearer or a btci_ key with the ops:agent scope.
PATCH /v1/orgs/{id}/members/{account_id}
Change a member's role
Spec S5.5 FR-11, admin at aal 2. Promotion to admin needs the member's second factor (FR-8); the last admin cannot step down (409).
- Auth
- An operator credential as the bearer; every call is audited.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
id required | path | integer (int64) | — |
account_id required | path | integer (int64) | — |
Request body
schema
rolestring required · one of "admin", "member", "billing"
Response 200
The new role.
schema
account_idinteger (int64) requiredrolestring required
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).401— Missing or invalid bearer (unauthorized).403— The operator lacks the role or kind the action needs, or is switched off (forbidden).404— Unknown to the index and, for transactions, to the node mempool.409— The state refuses the change (conflict): an open dispute by this caller exists already, or the dispute or claim is not open any more.501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X PATCH https://api.btcintel.io/v1/orgs/1/members/<account_id> \
-H 'Authorization: Bearer $BTCI_KEY' \
-H 'Content-Type: application/json' \
-d '{"role":"admin"}' | jqAn operator credential: the ops bearer or a btci_ key with the ops:agent scope.
DELETE /v1/orgs/{id}/members/{account_id}
Remove a member, or leave
Spec S5.5 FR-11: an admin at aal 2 removes a member; any member removes themselves; the last admin cannot go (409).
- Auth
- An operator credential as the bearer; every call is audited.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
id required | path | integer (int64) | — |
account_id required | path | integer (int64) | — |
Response 200
Removed.
schema
removedinteger (int64) required
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).401— Missing or invalid bearer (unauthorized).403— The operator lacks the role or kind the action needs, or is switched off (forbidden).404— Unknown to the index and, for transactions, to the node mempool.409— The state refuses the change (conflict): an open dispute by this caller exists already, or the dispute or claim is not open any more.501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X DELETE https://api.btcintel.io/v1/orgs/1/members/<account_id> \
-H 'Authorization: Bearer $BTCI_KEY' | jqAn operator credential: the ops bearer or a btci_ key with the ops:agent scope.
GET /v1/orgs/{id}/invites
The open invitations
Spec S5.5 FR-11, admin.
- Auth
- An operator credential as the bearer; every call is audited.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
id required | path | integer (int64) | — |
Response 200
The invitations.
schema
invitesarray of OrgInvite requiredidinteger (int64) requiredemailstring requiredrolestring required · one of "admin", "member", "billing"created_atstring (date-time) requiredexpires_atstring (date-time) required
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).401— Missing or invalid bearer (unauthorized).403— The operator lacks the role or kind the action needs, or is switched off (forbidden).404— Unknown to the index and, for transactions, to the node mempool.501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s https://api.btcintel.io/v1/orgs/1/invites \
-H 'Authorization: Bearer $BTCI_KEY' | jqAn operator credential: the ops bearer or a btci_ key with the ops:agent scope.
POST /v1/orgs/{id}/invites
Invite an address
Spec S5.5 FR-11, admin at aal 2. A link to the address (seven days, single use, three per address per day); the invitee's domain is not checked.
- Auth
- An operator credential as the bearer; every call is audited.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
id required | path | integer (int64) | — |
Request body
schema
emailstring requiredrolestring required · one of "admin", "member", "billing"
Response 201
The invitation.
schema
inviteOrgInvite requiredidinteger (int64) requiredemailstring requiredrolestring required · one of "admin", "member", "billing"created_atstring (date-time) requiredexpires_atstring (date-time) required
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).401— Missing or invalid bearer (unauthorized).403— The operator lacks the role or kind the action needs, or is switched off (forbidden).404— Unknown to the index and, for transactions, to the node mempool.429—quota_exceeded(spec S3.1 FR-4): the caller's tier ran out of requests for the minute or the day.Retry-Aftersays when to try again; every rate-limited answer carriesX-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-ResetandX-RateLimit-Tier. While the deployment runs in log-only mode the decision is logged instead andX-RateLimit-Policy: log-onlyis set.501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X POST https://api.btcintel.io/v1/orgs/1/invites \
-H 'Authorization: Bearer $BTCI_KEY' \
-H 'Content-Type: application/json' \
-d '{"email":"…","role":"admin"}' | jqAn operator credential: the ops bearer or a btci_ key with the ops:agent scope.
GET /v1/orgs/{id}/audit
The organisation's audit rows
Spec S5.5 FR-11, admin: creation, roles, removals, invitations, keys.
- Auth
- An operator credential as the bearer; every call is audited.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
id required | path | integer (int64) | — |
Response 200
The rows, newest first.
schema
auditarray of object required
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).401— Missing or invalid bearer (unauthorized).403— The operator lacks the role or kind the action needs, or is switched off (forbidden).404— Unknown to the index and, for transactions, to the node mempool.501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s https://api.btcintel.io/v1/orgs/1/audit \
-H 'Authorization: Bearer $BTCI_KEY' | jqAn operator credential: the ops bearer or a btci_ key with the ops:agent scope.
GET /v1/orgs/{id}/keys
The organisation's keys
Spec S5.5 FR-12, any member: the rows, never a secret.
- Auth
- An operator credential as the bearer; every call is audited.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
id required | path | integer (int64) | — |
Response 200
The keys.
schema
keysarray of KeyInfo requiredidintegerprefixstring · one of "btci_", "btci_anon_"tierstring · one of "t1", "t2", "t4"scopesarray of stringallowed_npubsarray of stringlabelstring | nulloperator_idstring | nullcreated_atstring (date-time)expires_atstring | null (date-time)last_used_onstring | nullrevoked_atstring | null (date-time)quotaQuotarequests_per_minintegerburst_per_minintegerrequests_per_dayintegerbulk_max_subjectsintegerpublish_per_dayintegerfeedback_per_dayinteger — Feedback entries per caller per UTC day (CC-8, spec S3.4).proposals_per_dayinteger — Curated proposals per caller per UTC day (CC-8, spec S5.1 FR-10).disputes_per_dayinteger — Disputes per caller per UTC day (CC-8, spec S5.3 FR-1).scopesarray of string
usage_todayobjecttotalintegerby_routeobjectnotestring
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).401— Missing or invalid bearer (unauthorized).403— The operator lacks the role or kind the action needs, or is switched off (forbidden).404— Unknown to the index and, for transactions, to the node mempool.501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s https://api.btcintel.io/v1/orgs/1/keys \
-H 'Authorization: Bearer $BTCI_KEY' | jqAn operator credential: the ops bearer or a btci_ key with the ops:agent scope.
POST /v1/orgs/{id}/keys
Issue a key owned by the organisation
Spec S5.5 FR-12, admin at aal 2: a btci_ key of tier t4 with scopes within t4's, at most twenty live keys; the secret is shown once.
- Auth
- An operator credential as the bearer; every call is audited.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
id required | path | integer (int64) | — |
Request body
schema
namestring required · min length 1 · max length 80scopesarray of string — Within t4's scopes; t4's by default.
Response 201
The key and its secret.
schema
secretstring required — Shown once.keyKeyInfo required — A key row without its secret (spec S3.1 FR-6).idintegerprefixstring · one of "btci_", "btci_anon_"tierstring · one of "t1", "t2", "t4"scopesarray of stringallowed_npubsarray of stringlabelstring | nulloperator_idstring | nullcreated_atstring (date-time)expires_atstring | null (date-time)last_used_onstring | nullrevoked_atstring | null (date-time)quotaQuotarequests_per_minintegerburst_per_minintegerrequests_per_dayintegerbulk_max_subjectsintegerpublish_per_dayintegerfeedback_per_dayinteger — Feedback entries per caller per UTC day (CC-8, spec S3.4).proposals_per_dayinteger — Curated proposals per caller per UTC day (CC-8, spec S5.1 FR-10).disputes_per_dayinteger — Disputes per caller per UTC day (CC-8, spec S5.3 FR-1).scopesarray of string
usage_todayobjecttotalintegerby_routeobjectnotestring
notestring
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).401— Missing or invalid bearer (unauthorized).403— The operator lacks the role or kind the action needs, or is switched off (forbidden).404— Unknown to the index and, for transactions, to the node mempool.409— The state refuses the change (conflict): an open dispute by this caller exists already, or the dispute or claim is not open any more.501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X POST https://api.btcintel.io/v1/orgs/1/keys \
-H 'Authorization: Bearer $BTCI_KEY' \
-H 'Content-Type: application/json' \
-d '{"name":"…"}' | jqAn operator credential: the ops bearer or a btci_ key with the ops:agent scope.
DELETE /v1/orgs/{id}/keys/{key_id}
Revoke a key of the organisation
Spec S5.5 FR-12, admin at aal 2; audited.
- Auth
- An operator credential as the bearer; every call is audited.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
id required | path | integer (int64) | — |
key_id required | path | integer (int64) | — |
Response 200
Revoked.
schema
revokedinteger (int64) required
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).401— Missing or invalid bearer (unauthorized).403— The operator lacks the role or kind the action needs, or is switched off (forbidden).404— Unknown to the index and, for transactions, to the node mempool.501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X DELETE https://api.btcintel.io/v1/orgs/1/keys/<key_id> \
-H 'Authorization: Bearer $BTCI_KEY' | jqAn operator credential: the ops bearer or a btci_ key with the ops:agent scope.
GET /v1/auth/keys
The account's keys
Spec S5.5 FR-12: the rows, never a secret.
- Auth
- An operator credential as the bearer; every call is audited.
Response 200
The keys.
schema
keysarray of KeyInfo requiredidintegerprefixstring · one of "btci_", "btci_anon_"tierstring · one of "t1", "t2", "t4"scopesarray of stringallowed_npubsarray of stringlabelstring | nulloperator_idstring | nullcreated_atstring (date-time)expires_atstring | null (date-time)last_used_onstring | nullrevoked_atstring | null (date-time)quotaQuotarequests_per_minintegerburst_per_minintegerrequests_per_dayintegerbulk_max_subjectsintegerpublish_per_dayintegerfeedback_per_dayinteger — Feedback entries per caller per UTC day (CC-8, spec S3.4).proposals_per_dayinteger — Curated proposals per caller per UTC day (CC-8, spec S5.1 FR-10).disputes_per_dayinteger — Disputes per caller per UTC day (CC-8, spec S5.3 FR-1).scopesarray of string
usage_todayobjecttotalintegerby_routeobjectnotestring
Errors
401— Missing or invalid bearer (unauthorized).403— The operator lacks the role or kind the action needs, or is switched off (forbidden).501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s https://api.btcintel.io/v1/auth/keys \
-H 'Authorization: Bearer $BTCI_KEY' | jqAn operator credential: the ops bearer or a btci_ key with the ops:agent scope.
POST /v1/auth/keys
Issue a key owned by the account
Spec S5.5 FR-12, aal 2: a btci_ key of tier t4 with scopes within t4's, at most ten live keys; the secret is shown once.
- Auth
- An operator credential as the bearer; every call is audited.
Request body
schema
namestring required · min length 1 · max length 80scopesarray of string — Within t4's scopes; t4's by default.
Response 201
The key and its secret.
schema
secretstring required — Shown once.keyKeyInfo required — A key row without its secret (spec S3.1 FR-6).idintegerprefixstring · one of "btci_", "btci_anon_"tierstring · one of "t1", "t2", "t4"scopesarray of stringallowed_npubsarray of stringlabelstring | nulloperator_idstring | nullcreated_atstring (date-time)expires_atstring | null (date-time)last_used_onstring | nullrevoked_atstring | null (date-time)quotaQuotarequests_per_minintegerburst_per_minintegerrequests_per_dayintegerbulk_max_subjectsintegerpublish_per_dayintegerfeedback_per_dayinteger — Feedback entries per caller per UTC day (CC-8, spec S3.4).proposals_per_dayinteger — Curated proposals per caller per UTC day (CC-8, spec S5.1 FR-10).disputes_per_dayinteger — Disputes per caller per UTC day (CC-8, spec S5.3 FR-1).scopesarray of string
usage_todayobjecttotalintegerby_routeobjectnotestring
notestring
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).401— Missing or invalid bearer (unauthorized).403— The operator lacks the role or kind the action needs, or is switched off (forbidden).409— The state refuses the change (conflict): an open dispute by this caller exists already, or the dispute or claim is not open any more.501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X POST https://api.btcintel.io/v1/auth/keys \
-H 'Authorization: Bearer $BTCI_KEY' \
-H 'Content-Type: application/json' \
-d '{"name":"…"}' | jqAn operator credential: the ops bearer or a btci_ key with the ops:agent scope.
DELETE /v1/auth/keys/{key_id}
Revoke a key of the account
Spec S5.5 FR-12, aal 2; audited.
- Auth
- An operator credential as the bearer; every call is audited.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
key_id required | path | integer (int64) | — |
Response 200
Revoked.
schema
revokedinteger (int64) required
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).401— Missing or invalid bearer (unauthorized).403— The operator lacks the role or kind the action needs, or is switched off (forbidden).404— Unknown to the index and, for transactions, to the node mempool.501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X DELETE https://api.btcintel.io/v1/auth/keys/<key_id> \
-H 'Authorization: Bearer $BTCI_KEY' | jqAn operator credential: the ops bearer or a btci_ key with the ops:agent scope.
GET /v1/auth/webauthn
The account's passkeys
Spec S5.5 FR-4: id, name, when created and last used, the backup flags; never a key.
- Auth
- An operator credential as the bearer; every call is audited.
Response 200
The passkeys.
schema
passkeysarray of Passkey requiredidinteger (int64) requirednamestring requiredcreated_atstring (date-time) requiredlast_used_atstring | null (date-time)backup_eligiblebooleanbacked_upbooleantransportsarray of string
Errors
401— Missing or invalid bearer (unauthorized).403— The operator lacks the role or kind the action needs, or is switched off (forbidden).501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s https://api.btcintel.io/v1/auth/webauthn \
-H 'Authorization: Bearer $BTCI_KEY' | jqAn operator credential: the ops bearer or a btci_ key with the ops:agent scope.
POST /v1/auth/webauthn/register/begin
Start registering a passkey
Spec S5.5 FR-4 (WebAuthn Level 3): the creation options for navigator.credentials.create — a discoverable credential with user verification required, the site's host as the relying party id, the account's other passkeys excluded. The first factor may be registered at aal 1 from a session signed in within the last 15 minutes (CP4-3), else 403 asking for a new sign-in; another one needs aal 2 (FR-7). Ten per account (409). The ceremony lasts five minutes.
- Auth
- An operator credential as the bearer; every call is audited.
Request body (optional)
schema
namestring · max length 80
Response 201
The ceremony id and the options.
schema
idstring required — Send it back with the browser's answer.optionsobject required — The WebAuthn options (publicKeyinside), base64url-encoded binary fields as the browser'sparseCreationOptionsFromJSON/parseRequestOptionsFromJSONexpect.expires_atstring (date-time) required
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).401— Missing or invalid bearer (unauthorized).403— The operator lacks the role or kind the action needs, or is switched off (forbidden).409— The state refuses the change (conflict): an open dispute by this caller exists already, or the dispute or claim is not open any more.501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X POST https://api.btcintel.io/v1/auth/webauthn/register/begin \
-H 'Authorization: Bearer $BTCI_KEY' \
-H 'Content-Type: application/json' \
-d '{}' | jqAn operator credential: the ops bearer or a btci_ key with the ops:agent scope.
POST /v1/auth/webauthn/register/finish
Finish registering a passkey
Spec S5.5 FR-4. credential is the browser's PublicKeyCredential as JSON (toJSON()); the attestation is verified against the ceremony, the passkey is stored and named, this session is lifted to aal 2 for ten minutes, and the account's first factor brings its ten recovery codes (FR-6).
- Auth
- An operator credential as the bearer; every call is audited.
Request body
schema
idstring required — The ceremony id.namestring · max length 80credentialobject required
Response 201
Registered.
schema
enrolledstring required · one of "passkey"passkeyPasskey requiredidinteger (int64) requirednamestring requiredcreated_atstring (date-time) requiredlast_used_atstring | null (date-time)backup_eligiblebooleanbacked_upbooleantransportsarray of string
recovery_codesarray of string — Only with the account's first factor.aalinteger required · one of 2aal_untilstring (date-time) required
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).401— Missing or invalid bearer (unauthorized).403— The operator lacks the role or kind the action needs, or is switched off (forbidden).404— Unknown to the index and, for transactions, to the node mempool.501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X POST https://api.btcintel.io/v1/auth/webauthn/register/finish \
-H 'Authorization: Bearer $BTCI_KEY' \
-H 'Content-Type: application/json' \
-d '{"id":"…","credential":{}}' | jqAn operator credential: the ops bearer or a btci_ key with the ops:agent scope.
POST /v1/auth/webauthn/authenticate/begin
Start a passkey sign-in or step-up
Spec S5.5 FR-4: the request options for navigator.credentials.get, discoverable (no account is named) with user verification required. Five minutes; sixty starts per client address per hour.
Response 201
The ceremony id and the options.
schema
idstring required — Send it back with the browser's answer.optionsobject required — The WebAuthn options (publicKeyinside), base64url-encoded binary fields as the browser'sparseCreationOptionsFromJSON/parseRequestOptionsFromJSONexpect.expires_atstring (date-time) required
Errors
429—quota_exceeded(spec S3.1 FR-4): the caller's tier ran out of requests for the minute or the day.Retry-Aftersays when to try again; every rate-limited answer carriesX-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-ResetandX-RateLimit-Tier. While the deployment runs in log-only mode the decision is logged instead andX-RateLimit-Policy: log-onlyis set.501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X POST https://api.btcintel.io/v1/auth/webauthn/authenticate/begin | jqPOST /v1/auth/webauthn/authenticate/finish
Finish a passkey sign-in or step-up
Spec S5.5 FR-4 and FR-7. credential is the browser's assertion as JSON. Without a session, the passkey opens one at aal 2 with amr [passkey] (201); with a session of the same account already on the request, it is a step-up to aal 2 for ten minutes (200). A signature counter that went backwards is refused. Thirty sign-ins per client address per hour.
Request body
schema
idstring required — The ceremony id.credentialobject required
Response 200
Stepped up.
schema
aalinteger required · one of 2aal_untilstring (date-time) requiredmethodstring required · one of "passkey"
Response 201
A session at aal 2; the cookie is set.
schema
accountobject requiredidinteger (int64) requiredemailstringdisplay_namestringcreated_atstring (date-time) required
tierstring required · one of "t4"expires_atstring (date-time) requiredsession_idstring required — The row id (SHA-256 of the cookie token) as/v1/auth/melists it.aalinteger required · one of 1, 2amrarray of string requiredpassword_reset_onlybooleannextstring — Where the explorer lands after a provider link (POST /v1/auth/oauth/confirm): the path the flow started with.signing_identitySigningIdentity — The account's Nostr key when it has one; while custodied signing is on, a sign-in gives an account without one its custodied key first (spec S5.9 FR-1).pubkeystring required — 64 hex characters.npubstring requiredsourcestring required · one of "custodied", "nip07", "nip46", "nip55"linked_atstring (date-time) requiredexportableboolean required — True for a custodied key:POST /v1/auth/npub/exporthands it over.exported_atstring (date-time) — When a custodied key was last exported; absent until then, and while the signer does not answer.clientsarray of SignerClient — The NIP-46 apps connected to a custodied key (spec S5.6 FR-4); empty when none, absent while the signer does not answer.client_pubkeystring required — The app's pubkey, 64 hex characters.namestring required — What the account called the app when it made the link; may be empty.permsarray of string required — What the app may ask for:sign_event:<kind>,sign_event,nip44_encrypt,nip44_decrypt,nip04_encrypt,nip04_decrypt.connected_atstring (date-time) requiredlast_used_atstring (date-time) — Absent until the app's first request after connecting.
quotaQuotarequests_per_minintegerburst_per_minintegerrequests_per_dayintegerbulk_max_subjectsintegerpublish_per_dayintegerfeedback_per_dayinteger — Feedback entries per caller per UTC day (CC-8, spec S3.4).proposals_per_dayinteger — Curated proposals per caller per UTC day (CC-8, spec S5.1 FR-10).disputes_per_dayinteger — Disputes per caller per UTC day (CC-8, spec S5.3 FR-1).scopesarray of string
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).401— Missing or invalid bearer (unauthorized).404— Unknown to the index and, for transactions, to the node mempool.429—quota_exceeded(spec S3.1 FR-4): the caller's tier ran out of requests for the minute or the day.Retry-Aftersays when to try again; every rate-limited answer carriesX-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-ResetandX-RateLimit-Tier. While the deployment runs in log-only mode the decision is logged instead andX-RateLimit-Policy: log-onlyis set.501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X POST https://api.btcintel.io/v1/auth/webauthn/authenticate/finish \
-H 'Content-Type: application/json' \
-d '{"id":"…","credential":{}}' | jqDELETE /v1/auth/webauthn/{id}
Remove a passkey
Spec S5.5 FR-4, aal 2. The last factor of an organisation admin or a key manager cannot go (FR-8, 403); removing the account's last factor voids its recovery codes.
- Auth
- An operator credential as the bearer; every call is audited.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
id required | path | integer (int64) | — |
Response 200
Removed.
schema
removedinteger (int64) required
Errors
400— Malformed input (bad hex, wrong-network address, bad vout).401— Missing or invalid bearer (unauthorized).403— The operator lacks the role or kind the action needs, or is switched off (forbidden).404— Unknown to the index and, for transactions, to the node mempool.501— The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCEunset).
Example
curl -s -X DELETE https://api.btcintel.io/v1/auth/webauthn/1 \
-H 'Authorization: Bearer $BTCI_KEY' | jqAn operator credential: the ops bearer or a btci_ key with the ops:agent scope.