BTCintel
nodeok
mempool68,918 tx
node next1.08 sat/vB
retarget40 blocks
chainmainnet

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

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
  • email string required — Normalised to lower case; plus-addresses are kept.
  • password string required · min length 1 · max length 128

Response 202

Accepted; the answer does not say whether the address had an account.

schema
  • accepted boolean required
  • next string — 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_SEQUENCE unset).

Example

curl -s -X POST https://api.btcintel.io/v1/auth/signup \
  -H 'Content-Type: application/json' \
  -d '{"email":"…","password":"…"}' | jq

POST /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
  • token string required — The token from the e-mail link (URL-safe base64).

Response 201

The account and its session; the cookie is set.

schema
  • account object required
    • id integer (int64) required
    • email string
    • display_name string
    • created_at string (date-time) required
  • tier string required · one of "t4"
  • expires_at string (date-time) required
  • session_id string required — The row id (SHA-256 of the cookie token) as /v1/auth/me lists it.
  • aal integer required · one of 1, 2
  • amr array of string required
  • password_reset_only boolean
  • next string — Where the explorer lands after a provider link (POST /v1/auth/oauth/confirm): the path the flow started with.
  • signing_identity SigningIdentity — 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).
    • pubkey string required — 64 hex characters.
    • npub string required
    • source string required · one of "custodied", "nip07", "nip46", "nip55"
    • linked_at string (date-time) required
    • exportable boolean required — True for a custodied key: POST /v1/auth/npub/export hands it over.
    • exported_at string (date-time) — When a custodied key was last exported; absent until then, and while the signer does not answer.
    • clients array 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_pubkey string required — The app's pubkey, 64 hex characters.
      • name string required — What the account called the app when it made the link; may be empty.
      • perms array of string required — What the app may ask for: sign_event:<kind>, sign_event, nip44_encrypt, nip44_decrypt, nip04_encrypt, nip04_decrypt.
      • connected_at string (date-time) required
      • last_used_at string (date-time) — Absent until the app's first request after connecting.
  • quota Quota
    • requests_per_min integer
    • burst_per_min integer
    • requests_per_day integer
    • bulk_max_subjects integer
    • publish_per_day integer
    • feedback_per_day integer — Feedback entries per caller per UTC day (CC-8, spec S3.4).
    • proposals_per_day integer — Curated proposals per caller per UTC day (CC-8, spec S5.1 FR-10).
    • disputes_per_day integer — Disputes per caller per UTC day (CC-8, spec S5.3 FR-1).
    • scopes array 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_SEQUENCE unset).

Example

curl -s -X POST https://api.btcintel.io/v1/auth/verify \
  -H 'Content-Type: application/json' \
  -d '{"token":"…"}' | jq

POST /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
  • email string required — Normalised to lower case; plus-addresses are kept.
  • password string required · min length 1 · max length 128

Response 201

The account and its session; the cookie is set.

schema
  • account object required
    • id integer (int64) required
    • email string
    • display_name string
    • created_at string (date-time) required
  • tier string required · one of "t4"
  • expires_at string (date-time) required
  • session_id string required — The row id (SHA-256 of the cookie token) as /v1/auth/me lists it.
  • aal integer required · one of 1, 2
  • amr array of string required
  • password_reset_only boolean
  • next string — Where the explorer lands after a provider link (POST /v1/auth/oauth/confirm): the path the flow started with.
  • signing_identity SigningIdentity — 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).
    • pubkey string required — 64 hex characters.
    • npub string required
    • source string required · one of "custodied", "nip07", "nip46", "nip55"
    • linked_at string (date-time) required
    • exportable boolean required — True for a custodied key: POST /v1/auth/npub/export hands it over.
    • exported_at string (date-time) — When a custodied key was last exported; absent until then, and while the signer does not answer.
    • clients array 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_pubkey string required — The app's pubkey, 64 hex characters.
      • name string required — What the account called the app when it made the link; may be empty.
      • perms array of string required — What the app may ask for: sign_event:<kind>, sign_event, nip44_encrypt, nip44_decrypt, nip04_encrypt, nip04_decrypt.
      • connected_at string (date-time) required
      • last_used_at string (date-time) — Absent until the app's first request after connecting.
  • quota Quota
    • requests_per_min integer
    • burst_per_min integer
    • requests_per_day integer
    • bulk_max_subjects integer
    • publish_per_day integer
    • feedback_per_day integer — Feedback entries per caller per UTC day (CC-8, spec S3.4).
    • proposals_per_day integer — Curated proposals per caller per UTC day (CC-8, spec S5.1 FR-10).
    • disputes_per_day integer — Disputes per caller per UTC day (CC-8, spec S5.3 FR-1).
    • scopes array 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-After says when to try again; every rate-limited answer carries X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset and X-RateLimit-Tier. While the deployment runs in log-only mode the decision is logged instead and X-RateLimit-Policy: log-only is set.
  • 501 — The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCE unset).

Example

curl -s -X POST https://api.btcintel.io/v1/auth/password \
  -H 'Content-Type: application/json' \
  -d '{"email":"…","password":"…"}' | jq

PUT /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
  • password string required · min length 12 · max length 128

Response 200

The password is set.

schema
  • password_set boolean required
  • sessions_revoked integer 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_SEQUENCE unset).

Example

curl -s -X PUT https://api.btcintel.io/v1/auth/password \
  -H 'Authorization: Bearer $BTCI_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"password":"…"}' | jq

An operator credential: the ops bearer or a btci_ key with the ops:agent scope.

POST /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
  • token string required — The token from the e-mail link (URL-safe base64).

Response 201

The account and its session; the cookie is set.

schema
  • account object required
    • id integer (int64) required
    • email string
    • display_name string
    • created_at string (date-time) required
  • tier string required · one of "t4"
  • expires_at string (date-time) required
  • session_id string required — The row id (SHA-256 of the cookie token) as /v1/auth/me lists it.
  • aal integer required · one of 1, 2
  • amr array of string required
  • password_reset_only boolean
  • next string — Where the explorer lands after a provider link (POST /v1/auth/oauth/confirm): the path the flow started with.
  • signing_identity SigningIdentity — 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).
    • pubkey string required — 64 hex characters.
    • npub string required
    • source string required · one of "custodied", "nip07", "nip46", "nip55"
    • linked_at string (date-time) required
    • exportable boolean required — True for a custodied key: POST /v1/auth/npub/export hands it over.
    • exported_at string (date-time) — When a custodied key was last exported; absent until then, and while the signer does not answer.
    • clients array 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_pubkey string required — The app's pubkey, 64 hex characters.
      • name string required — What the account called the app when it made the link; may be empty.
      • perms array of string required — What the app may ask for: sign_event:<kind>, sign_event, nip44_encrypt, nip44_decrypt, nip04_encrypt, nip04_decrypt.
      • connected_at string (date-time) required
      • last_used_at string (date-time) — Absent until the app's first request after connecting.
  • quota Quota
    • requests_per_min integer
    • burst_per_min integer
    • requests_per_day integer
    • bulk_max_subjects integer
    • publish_per_day integer
    • feedback_per_day integer — Feedback entries per caller per UTC day (CC-8, spec S3.4).
    • proposals_per_day integer — Curated proposals per caller per UTC day (CC-8, spec S5.1 FR-10).
    • disputes_per_day integer — Disputes per caller per UTC day (CC-8, spec S5.3 FR-1).
    • scopes array 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_SEQUENCE unset).

Example

curl -s -X POST https://api.btcintel.io/v1/auth/link/verify \
  -H 'Content-Type: application/json' \
  -d '{"token":"…"}' | jq

POST /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
  • email string required

Response 202

Accepted; the answer does not say whether the address has an account.

schema
  • accepted boolean required
  • next string — 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_SEQUENCE unset).

Example

curl -s -X POST https://api.btcintel.io/v1/auth/reset \
  -H 'Content-Type: application/json' \
  -d '{"email":"…"}' | jq

POST /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
  • token string 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
  • account object required
    • id integer (int64) required
    • email string
    • display_name string
    • created_at string (date-time) required
  • tier string required · one of "t4"
  • expires_at string (date-time) required
  • session_id string required — The row id (SHA-256 of the cookie token) as /v1/auth/me lists it.
  • aal integer required · one of 1, 2
  • amr array of string required
  • password_reset_only boolean
  • next string — Where the explorer lands after a provider link (POST /v1/auth/oauth/confirm): the path the flow started with.
  • signing_identity SigningIdentity — 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).
    • pubkey string required — 64 hex characters.
    • npub string required
    • source string required · one of "custodied", "nip07", "nip46", "nip55"
    • linked_at string (date-time) required
    • exportable boolean required — True for a custodied key: POST /v1/auth/npub/export hands it over.
    • exported_at string (date-time) — When a custodied key was last exported; absent until then, and while the signer does not answer.
    • clients array 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_pubkey string required — The app's pubkey, 64 hex characters.
      • name string required — What the account called the app when it made the link; may be empty.
      • perms array of string required — What the app may ask for: sign_event:<kind>, sign_event, nip44_encrypt, nip44_decrypt, nip04_encrypt, nip04_decrypt.
      • connected_at string (date-time) required
      • last_used_at string (date-time) — Absent until the app's first request after connecting.
  • quota Quota
    • requests_per_min integer
    • burst_per_min integer
    • requests_per_day integer
    • bulk_max_subjects integer
    • publish_per_day integer
    • feedback_per_day integer — Feedback entries per caller per UTC day (CC-8, spec S3.4).
    • proposals_per_day integer — Curated proposals per caller per UTC day (CC-8, spec S5.1 FR-10).
    • disputes_per_day integer — Disputes per caller per UTC day (CC-8, spec S5.3 FR-1).
    • scopes array 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_SEQUENCE unset).

Example

curl -s -X POST https://api.btcintel.io/v1/auth/reset/verify \
  -H 'Content-Type: application/json' \
  -d '{"token":"…"}' | jq

PATCH /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_name string · max length 80
  • email string

Response 200

The account after the change.

schema
  • account AccountInfo required
    • id integer (int64) required
    • email string
    • display_name string
    • created_at string (date-time) required

Response 202

The e-mail change waits for the link sent to the new address.

schema
  • accepted boolean required
  • next string — 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_SEQUENCE unset).

Example

curl -s -X PATCH https://api.btcintel.io/v1/auth/account \
  -H 'Authorization: Bearer $BTCI_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}' | jq

An 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
  • closed boolean required
  • grace_until string (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_SEQUENCE unset).

Example

curl -s -X DELETE https://api.btcintel.io/v1/auth/account \
  -H 'Authorization: Bearer $BTCI_KEY' | jq

An 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
  • token string required — The token from the e-mail link (URL-safe base64).

Response 200

The account with its new address.

schema
  • account AccountInfo required
    • id integer (int64) required
    • email string
    • display_name string
    • created_at string (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_SEQUENCE unset).

Example

curl -s -X POST https://api.btcintel.io/v1/auth/email/verify \
  -H 'Content-Type: application/json' \
  -d '{"token":"…"}' | jq

GET /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_at string (date-time) required
  • account AccountInfo required
    • id integer (int64) required
    • email string
    • display_name string
    • created_at string (date-time) required
  • sessions array of object required
  • logins array of object — The sign-in providers bound to the account (spec S5.5 FR-13); empty when none.
    • provider string required · one of "google", "github", "apple", "oidc"
    • subject string required — The provider's stable identifier.
    • email string — The address the provider reported.
    • verified boolean required
    • created_at string (date-time) required
  • audit array 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_SEQUENCE unset).

Example

curl -s https://api.btcintel.io/v1/auth/export \
  -H 'Authorization: Bearer $BTCI_KEY' | jq

An 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
  • name string — How the person calls the app (default: Authenticator app). · max length 80

Response 201

The pending secret.

schema
  • secret string required — Base32, for an app without a camera.
  • otpauth_url string required
  • expires_at string (date-time) required
  • next string

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_SEQUENCE unset).

Example

curl -s -X POST https://api.btcintel.io/v1/auth/totp/enrol \
  -H 'Authorization: Bearer $BTCI_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}' | jq

An 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
  • code string required — Six digits; spaces are ignored.

Response 201

Enrolled.

schema
  • enrolled string required · one of "totp"
  • recovery_codes array of string required
  • aal integer required · one of 2
  • aal_until string (date-time) required
  • next string

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-After says when to try again; every rate-limited answer carries X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset and X-RateLimit-Tier. While the deployment runs in log-only mode the decision is logged instead and X-RateLimit-Policy: log-only is set.
  • 501 — The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCE unset).

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":"…"}' | jq

An 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
  • disabled string 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_SEQUENCE unset).

Example

curl -s -X POST https://api.btcintel.io/v1/auth/totp/disable \
  -H 'Authorization: Bearer $BTCI_KEY' | jq

An 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_codes array 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_SEQUENCE unset).

Example

curl -s -X POST https://api.btcintel.io/v1/auth/recovery-codes \
  -H 'Authorization: Bearer $BTCI_KEY' | jq

An 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
  • code string
  • recovery_code string

Response 200

Stepped up.

schema
  • aal integer required · one of 2
  • aal_until string (date-time) required
  • method string required · one of "totp", "recovery"
  • recovery_codes_left integer

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-After says when to try again; every rate-limited answer carries X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset and X-RateLimit-Tier. While the deployment runs in log-only mode the decision is logged instead and X-RateLimit-Policy: log-only is set.
  • 501 — The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCE unset).

Example

curl -s -X POST https://api.btcintel.io/v1/auth/step-up \
  -H 'Authorization: Bearer $BTCI_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}' | jq

An 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
  • organisations array of Organisation required
    • id integer (int64) required
    • name string required
    • slug string required
    • created_at string (date-time) required
    • role string — 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_SEQUENCE unset).

Example

curl -s https://api.btcintel.io/v1/orgs \
  -H 'Authorization: Bearer $BTCI_KEY' | jq

An 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
  • name string required · min length 1 · max length 120

Response 201

The organisation and the creator's role.

schema
  • organisation Organisation required
    • id integer (int64) required
    • name string required
    • slug string required
    • created_at string (date-time) required
    • role string — 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_SEQUENCE unset).

Example

curl -s -X POST https://api.btcintel.io/v1/orgs \
  -H 'Authorization: Bearer $BTCI_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"name":"…"}' | jq

An 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
  • token string required — The token from the e-mail link (URL-safe base64).

Response 200

The organisation joined and the role.

schema
  • organisation Organisation required
    • id integer (int64) required
    • name string required
    • slug string required
    • created_at string (date-time) required
    • role string — 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_SEQUENCE unset).

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":"…"}' | jq

An 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

NameInTypeDescription
id requiredpathinteger (int64)—

Response 200

The organisation and its members.

schema
  • organisation Organisation required
    • id integer (int64) required
    • name string required
    • slug string required
    • created_at string (date-time) required
    • role string — The caller's role. · one of "admin", "member", "billing"
  • members array of OrgMember required
    • account_id integer (int64) required
    • role string required · one of "admin", "member", "billing"
    • joined_at string (date-time) required
    • display_name string
    • email string — 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_SEQUENCE unset).

Example

curl -s https://api.btcintel.io/v1/orgs/1 \
  -H 'Authorization: Bearer $BTCI_KEY' | jq

An 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

NameInTypeDescription
id requiredpathinteger (int64)—
account_id requiredpathinteger (int64)—

Request body

schema
  • role string required · one of "admin", "member", "billing"

Response 200

The new role.

schema
  • account_id integer (int64) required
  • role string 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_SEQUENCE unset).

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"}' | jq

An 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

NameInTypeDescription
id requiredpathinteger (int64)—
account_id requiredpathinteger (int64)—

Response 200

Removed.

schema
  • removed integer (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_SEQUENCE unset).

Example

curl -s -X DELETE https://api.btcintel.io/v1/orgs/1/members/<account_id> \
  -H 'Authorization: Bearer $BTCI_KEY' | jq

An 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

NameInTypeDescription
id requiredpathinteger (int64)—

Response 200

The invitations.

schema
  • invites array of OrgInvite required
    • id integer (int64) required
    • email string required
    • role string required · one of "admin", "member", "billing"
    • created_at string (date-time) required
    • expires_at string (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_SEQUENCE unset).

Example

curl -s https://api.btcintel.io/v1/orgs/1/invites \
  -H 'Authorization: Bearer $BTCI_KEY' | jq

An 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

NameInTypeDescription
id requiredpathinteger (int64)—

Request body

schema
  • email string required
  • role string required · one of "admin", "member", "billing"

Response 201

The invitation.

schema
  • invite OrgInvite required
    • id integer (int64) required
    • email string required
    • role string required · one of "admin", "member", "billing"
    • created_at string (date-time) required
    • expires_at string (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-After says when to try again; every rate-limited answer carries X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset and X-RateLimit-Tier. While the deployment runs in log-only mode the decision is logged instead and X-RateLimit-Policy: log-only is set.
  • 501 — The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCE unset).

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"}' | jq

An 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

NameInTypeDescription
id requiredpathinteger (int64)—

Response 200

The rows, newest first.

schema
  • audit array 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_SEQUENCE unset).

Example

curl -s https://api.btcintel.io/v1/orgs/1/audit \
  -H 'Authorization: Bearer $BTCI_KEY' | jq

An 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

NameInTypeDescription
id requiredpathinteger (int64)—

Response 200

The keys.

schema
  • keys array of KeyInfo required
    • id integer
    • prefix string · one of "btci_", "btci_anon_"
    • tier string · one of "t1", "t2", "t4"
    • scopes array of string
    • allowed_npubs array of string
    • label string | null
    • operator_id string | null
    • created_at string (date-time)
    • expires_at string | null (date-time)
    • last_used_on string | null
    • revoked_at string | null (date-time)
    • quota Quota
      • requests_per_min integer
      • burst_per_min integer
      • requests_per_day integer
      • bulk_max_subjects integer
      • publish_per_day integer
      • feedback_per_day integer — Feedback entries per caller per UTC day (CC-8, spec S3.4).
      • proposals_per_day integer — Curated proposals per caller per UTC day (CC-8, spec S5.1 FR-10).
      • disputes_per_day integer — Disputes per caller per UTC day (CC-8, spec S5.3 FR-1).
      • scopes array of string
    • usage_today object
      • total integer
      • by_route object
      • note string

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_SEQUENCE unset).

Example

curl -s https://api.btcintel.io/v1/orgs/1/keys \
  -H 'Authorization: Bearer $BTCI_KEY' | jq

An 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

NameInTypeDescription
id requiredpathinteger (int64)—

Request body

schema
  • name string required · min length 1 · max length 80
  • scopes array of string — Within t4's scopes; t4's by default.

Response 201

The key and its secret.

schema
  • secret string required — Shown once.
  • key KeyInfo required — A key row without its secret (spec S3.1 FR-6).
    • id integer
    • prefix string · one of "btci_", "btci_anon_"
    • tier string · one of "t1", "t2", "t4"
    • scopes array of string
    • allowed_npubs array of string
    • label string | null
    • operator_id string | null
    • created_at string (date-time)
    • expires_at string | null (date-time)
    • last_used_on string | null
    • revoked_at string | null (date-time)
    • quota Quota
      • requests_per_min integer
      • burst_per_min integer
      • requests_per_day integer
      • bulk_max_subjects integer
      • publish_per_day integer
      • feedback_per_day integer — Feedback entries per caller per UTC day (CC-8, spec S3.4).
      • proposals_per_day integer — Curated proposals per caller per UTC day (CC-8, spec S5.1 FR-10).
      • disputes_per_day integer — Disputes per caller per UTC day (CC-8, spec S5.3 FR-1).
      • scopes array of string
    • usage_today object
      • total integer
      • by_route object
      • note string
  • note string

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_SEQUENCE unset).

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":"…"}' | jq

An 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

NameInTypeDescription
id requiredpathinteger (int64)—
key_id requiredpathinteger (int64)—

Response 200

Revoked.

schema
  • revoked integer (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_SEQUENCE unset).

Example

curl -s -X DELETE https://api.btcintel.io/v1/orgs/1/keys/<key_id> \
  -H 'Authorization: Bearer $BTCI_KEY' | jq

An 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
  • keys array of KeyInfo required
    • id integer
    • prefix string · one of "btci_", "btci_anon_"
    • tier string · one of "t1", "t2", "t4"
    • scopes array of string
    • allowed_npubs array of string
    • label string | null
    • operator_id string | null
    • created_at string (date-time)
    • expires_at string | null (date-time)
    • last_used_on string | null
    • revoked_at string | null (date-time)
    • quota Quota
      • requests_per_min integer
      • burst_per_min integer
      • requests_per_day integer
      • bulk_max_subjects integer
      • publish_per_day integer
      • feedback_per_day integer — Feedback entries per caller per UTC day (CC-8, spec S3.4).
      • proposals_per_day integer — Curated proposals per caller per UTC day (CC-8, spec S5.1 FR-10).
      • disputes_per_day integer — Disputes per caller per UTC day (CC-8, spec S5.3 FR-1).
      • scopes array of string
    • usage_today object
      • total integer
      • by_route object
      • note 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_SEQUENCE unset).

Example

curl -s https://api.btcintel.io/v1/auth/keys \
  -H 'Authorization: Bearer $BTCI_KEY' | jq

An 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
  • name string required · min length 1 · max length 80
  • scopes array of string — Within t4's scopes; t4's by default.

Response 201

The key and its secret.

schema
  • secret string required — Shown once.
  • key KeyInfo required — A key row without its secret (spec S3.1 FR-6).
    • id integer
    • prefix string · one of "btci_", "btci_anon_"
    • tier string · one of "t1", "t2", "t4"
    • scopes array of string
    • allowed_npubs array of string
    • label string | null
    • operator_id string | null
    • created_at string (date-time)
    • expires_at string | null (date-time)
    • last_used_on string | null
    • revoked_at string | null (date-time)
    • quota Quota
      • requests_per_min integer
      • burst_per_min integer
      • requests_per_day integer
      • bulk_max_subjects integer
      • publish_per_day integer
      • feedback_per_day integer — Feedback entries per caller per UTC day (CC-8, spec S3.4).
      • proposals_per_day integer — Curated proposals per caller per UTC day (CC-8, spec S5.1 FR-10).
      • disputes_per_day integer — Disputes per caller per UTC day (CC-8, spec S5.3 FR-1).
      • scopes array of string
    • usage_today object
      • total integer
      • by_route object
      • note string
  • note string

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_SEQUENCE unset).

Example

curl -s -X POST https://api.btcintel.io/v1/auth/keys \
  -H 'Authorization: Bearer $BTCI_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"name":"…"}' | jq

An 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

NameInTypeDescription
key_id requiredpathinteger (int64)—

Response 200

Revoked.

schema
  • revoked integer (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_SEQUENCE unset).

Example

curl -s -X DELETE https://api.btcintel.io/v1/auth/keys/<key_id> \
  -H 'Authorization: Bearer $BTCI_KEY' | jq

An 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
  • passkeys array of Passkey required
    • id integer (int64) required
    • name string required
    • created_at string (date-time) required
    • last_used_at string | null (date-time)
    • backup_eligible boolean
    • backed_up boolean
    • transports array 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_SEQUENCE unset).

Example

curl -s https://api.btcintel.io/v1/auth/webauthn \
  -H 'Authorization: Bearer $BTCI_KEY' | jq

An 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
  • name string · max length 80

Response 201

The ceremony id and the options.

schema
  • id string required — Send it back with the browser's answer.
  • options object required — The WebAuthn options (publicKey inside), base64url-encoded binary fields as the browser's parseCreationOptionsFromJSON / parseRequestOptionsFromJSON expect.
  • expires_at string (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_SEQUENCE unset).

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 '{}' | jq

An 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
  • id string required — The ceremony id.
  • name string · max length 80
  • credential object required

Response 201

Registered.

schema
  • enrolled string required · one of "passkey"
  • passkey Passkey required
    • id integer (int64) required
    • name string required
    • created_at string (date-time) required
    • last_used_at string | null (date-time)
    • backup_eligible boolean
    • backed_up boolean
    • transports array of string
  • recovery_codes array of string — Only with the account's first factor.
  • aal integer required · one of 2
  • aal_until string (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_SEQUENCE unset).

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":{}}' | jq

An 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
  • id string required — Send it back with the browser's answer.
  • options object required — The WebAuthn options (publicKey inside), base64url-encoded binary fields as the browser's parseCreationOptionsFromJSON / parseRequestOptionsFromJSON expect.
  • expires_at string (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-After says when to try again; every rate-limited answer carries X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset and X-RateLimit-Tier. While the deployment runs in log-only mode the decision is logged instead and X-RateLimit-Policy: log-only is set.
  • 501 — The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCE unset).

Example

curl -s -X POST https://api.btcintel.io/v1/auth/webauthn/authenticate/begin | jq

POST /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
  • id string required — The ceremony id.
  • credential object required

Response 200

Stepped up.

schema
  • aal integer required · one of 2
  • aal_until string (date-time) required
  • method string required · one of "passkey"

Response 201

A session at aal 2; the cookie is set.

schema
  • account object required
    • id integer (int64) required
    • email string
    • display_name string
    • created_at string (date-time) required
  • tier string required · one of "t4"
  • expires_at string (date-time) required
  • session_id string required — The row id (SHA-256 of the cookie token) as /v1/auth/me lists it.
  • aal integer required · one of 1, 2
  • amr array of string required
  • password_reset_only boolean
  • next string — Where the explorer lands after a provider link (POST /v1/auth/oauth/confirm): the path the flow started with.
  • signing_identity SigningIdentity — 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).
    • pubkey string required — 64 hex characters.
    • npub string required
    • source string required · one of "custodied", "nip07", "nip46", "nip55"
    • linked_at string (date-time) required
    • exportable boolean required — True for a custodied key: POST /v1/auth/npub/export hands it over.
    • exported_at string (date-time) — When a custodied key was last exported; absent until then, and while the signer does not answer.
    • clients array 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_pubkey string required — The app's pubkey, 64 hex characters.
      • name string required — What the account called the app when it made the link; may be empty.
      • perms array of string required — What the app may ask for: sign_event:<kind>, sign_event, nip44_encrypt, nip44_decrypt, nip04_encrypt, nip04_decrypt.
      • connected_at string (date-time) required
      • last_used_at string (date-time) — Absent until the app's first request after connecting.
  • quota Quota
    • requests_per_min integer
    • burst_per_min integer
    • requests_per_day integer
    • bulk_max_subjects integer
    • publish_per_day integer
    • feedback_per_day integer — Feedback entries per caller per UTC day (CC-8, spec S3.4).
    • proposals_per_day integer — Curated proposals per caller per UTC day (CC-8, spec S5.1 FR-10).
    • disputes_per_day integer — Disputes per caller per UTC day (CC-8, spec S5.3 FR-1).
    • scopes array 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-After says when to try again; every rate-limited answer carries X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset and X-RateLimit-Tier. While the deployment runs in log-only mode the decision is logged instead and X-RateLimit-Policy: log-only is set.
  • 501 — The mempool engine is not enabled on this deployment (BITCOIN_ZMQ_SEQUENCE unset).

Example

curl -s -X POST https://api.btcintel.io/v1/auth/webauthn/authenticate/finish \
  -H 'Content-Type: application/json' \
  -d '{"id":"…","credential":{}}' | jq

DELETE /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

NameInTypeDescription
id requiredpathinteger (int64)—

Response 200

Removed.

schema
  • removed integer (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_SEQUENCE unset).

Example

curl -s -X DELETE https://api.btcintel.io/v1/auth/webauthn/1 \
  -H 'Authorization: Bearer $BTCI_KEY' | jq

An operator credential: the ops bearer or a btci_ key with the ops:agent scope.