Drops Protocol documentation

Grounded in the service's own OpenAPI 3.1 definition

API reference

Every parameter constraint, enum value and response field below is taken from the indexer's published interface definition. Paths are relative to the base URL of whichever Drops indexer you are pointed at; this page names no host, because the endpoints are the contract and the deployment is yours to choose.

Conventions

DefinitionOpenAPI 3.1, served by the indexer itself
AuthenticationNone. Every endpoint on this page is an unauthenticated public read.
PaginationOffset based: start and limit. Defaults differ per endpoint and are stated in each table.
OrderingLists are newest first unless an endpoint says otherwise.
Hex casingResponses emit lowercase hex, except dropmark, which is uppercase by definition.
Rate limitsNo rate-limit headers and no 429 response are declared for any Drops or Pacts read endpoint.
Administrative and operator surfaces are out of scope

The service also exposes authenticated operator endpoints for scanning, replay, reconciliation and metrics. They are not part of the protocol, are not public, and are deliberately not documented here.

Artifacts

GET /drops/inscriptions

List confirmed Drops artifacts.

Query parameters
NameTypeConstraintDefault
mimestringMaximum 80 charactersnone
addressstringMatches current or initial ownernone
txidstring^[0-9a-fA-F]{64}$none
markerenumdrops or drops-pact. bip110-op-drop is deliberately excluded.none
planHashstring^[0-9a-f]{64}$, matches a Pacts reference plan hashnone
startinteger0 to 100000000
limitinteger1 to 10020

Returns an object with total (integer, zero or more) and inscriptions (array of DropsInscription).

GET /drops/inscriptions/{dropId}

Fetch one artifact with its proof material. The path segment accepts several forms and the response always emits the full portable identity.

Accepted dropId forms
FormExample
Full portable identitydrops:mainnet:6b1f…91aa:d0
Shorthand6b1f…91aa:d0
Historical aliasi0 style input alias
Display sequenceThe deployment-local sequence number

Responses: 200 with a DropsInscription, or 404 with an Error.

Only the full identity is portable

The shorthand, alias and sequence forms are conveniences for one deployment. Store and exchange the full drops:<network>:<txid>:d<input> form.

GET /drops/inscriptions/{dropId}/body

The exact immutable body bytes, at most 256 of them. The response applies the passive-content serving policy: text/plain and the raster image types keep their declared media type and render inline; SVG, HTML, JavaScript, XML, JSON, PDF and any unknown type are served as an application/octet-stream attachment.

Response headers
HeaderValue
ETagThe body SHA-256, quoted
Cache-ControlLong-lived and immutable; the bytes at a Drop identity can never change
Content-Dispositioninline or attachment, per the serving policy
Content-Security-Policydefault-src 'none'; sandbox
X-Content-Type-Optionsnosniff

GET /drops/inscriptions/{dropId}/transfers

List confirmed drops-custody-v1 custody transitions for one artifact, newest first. Query parameters: start (integer 0 to 10000000, default 0) and limit (integer 1 to 100, default 20). Responses: 200, or 404 with an Error.

Pacts

The Pacts surface is read-only by contract

Any method other than GET on a Pacts path returns 405 with the error code PACTS_REFERENCE_READ_ONLY and a copy of the capability contract. This is the API-level expression of the reference-only boundary.

GET /drops/pacts/capabilities

The machine-readable capability boundary. Read this before building anything against Pacts. Every execution, custody, authorization, signature, broadcast, live-Cell, off-chain-policy and value-bearing authority field is false.

{
  "schemaVersion": 1,
  "mode": "reference",
  "supported": {
    "verifiedDrops": true,
    "recordedPactSeeds": true,
    "pactsReferences": true,
    "deterministicPrimitives": true,
    "localProofPackValidation": true
  },
  "authority": {
    "pactCell": false,
    "liveCells": false,
    "transaction": false,
    "authorization": false,
    "signature": false,
    "signatures": false,
    "broadcast": false,
    "custody": false,
    "contractExecution": false,
    "enforceableOffChainPolicy": false,
    "valueBearingPacts": false,
    "valueBearingAuthority": false
  },
  "recovery": {
    "status": "reference_only",
    "message": "...",
    "actions": ["..."]
  }
}

Every value shown is a constant in the interface definition, not an example. An implementation that returns anything else for these fields is not the reference Pacts surface.

GET /drops/pacts

List recorded immutable Pact Seeds, newest first. One query parameter: limit (integer 1 to 100, default 50). There is no offset parameter on this endpoint. The response carries data (array of PactDropRecord), count (0 to 100), notice (the reference-only notice string), and capability (the full capability object above).

GET /drops/pacts/{pactId}

Fetch one Pact Seed record. Path parameter pactId must match ^[0-9a-f]{64}$. Responses: 200 with a PactDropRecord, or 404.

Health and status

GET /drops/health

Returns status: "ok", protocol: "drops", ready: true, plus two objects. A 503 means a dependency is unavailable, or the scanner does not hold leadership or a current finalized state.

Fields worth reading before you trust a response
FieldTypeWhy it matters
data.networkstringWhich network these answers are about.
data.confirmationsRequiredinteger, at least 1The depth at which this deployment records state. Six or more on mainnet.
data.totalInscriptions, data.totalPactsintegerRecorded totals.
data.custodyIntegrityobjectProjection drift counters and a custodyHealthy boolean.
indexer.serviceRoleapi, scanner, allWhether this process scans, serves, or both.
indexer.statestringOnly synced means current to the finalized target.
indexer.scannerobjectLeadership state, one of eight values. See validation.
indexer.tipFresh, tipAgeSeconds, lagBlocksboolean, integer or nullHow far behind the chain tip this view is.
indexer.operatorActionRequiredbooleanTrue when the indexer has stopped and is waiting for a decision.

GET /drops/status

Totals and diagnostic counters, including in-memory rejection counts. The interface definition marks this payload as open and explicitly not authoritative. Use it for operations, not for protocol decisions.

Service-level endpoints

EndpointReturns
GET /liveLiveness only: status: "ok", protocol: "op-drop". Says nothing about readiness.
GET /readyReadiness, 200 or 503.
GET /healthCombined health: database, indexer, schema identity, and per-dependency status.
GET /versionRelease provenance, including minimumMainnetConfirmations, which is at least 6.

Schemas

DropsInscription

FieldType and constraint
dropId requiredstring, drops:<network>:<txid>:d<input>
markerenum: drops, drops-pact
mimestring
bodyBytesinteger, 1 to 256
bodySha256^[a-f0-9]{64}$
bodyUrlstring
dropmark^[0-9A-F]{10}$, decorative
creatorPubkey^[a-f0-9]{64}$
sequence, displayNameinteger at least 0, string. Presentation only.
initialOwnerAddress requiredstring or null
currentOwnerAddress requiredstring or null
custodyStatus requiredenum: active, burned, legacy_unresolved
currentCustodyOutpoint requirednull, or an object with txid, vout, scriptHex, valueSats
custody requiredobject; profile is the constant drops-custody-v1, plus status, currentOutpoint, scriptHex, valueSats, transferCount, lastTransferHeight, lastTransferTxid, verifiedAt, verifiedHeight, verifiedBlockHash, projectionVersion, verificationSource
reveal requiredobject: txid, input, height, blockHash
pactSeed, pactsReferencePresent when the body matched a Pact body profile

PactDropRecord

Required: id, number, marker, network, contentType, contentHash, dropmark, bodyHex, creatorPubkey, reveal, anchor, verification, finality, indexedAt.

  • network is one of mainnet, testnet, signet, regtest.
  • number is a presentation number, explicitly not an identity.
  • contentHash and creatorPubkey match ^[0-9a-f]{64}$; bodyHex matches ^(?:[0-9a-f]{2})+$.
  • verification.taprootCommitted is the constant true. A record only exists if its commitment verified.
  • finality.status is the constant finalized. Note that finalizedAt is typed as always null in the current definition, so do not rely on it for a timestamp; use reveal.height instead.
  • pactSeed and pactsReference appear when the body decoded as one of those profiles.

PactSeed

All of pactId, rulesetHash, abiHash, genesisStateRoot, policyRoot and dataAvailabilityPolicyHash match ^[0-9a-f]{64}$. engineId matches ^[a-z][a-z0-9-]{0,15}$. enforcementFloor is one of recorded, co-signed, template-enforced. Every field is required.

PactsReference

template matches ^[a-z][a-z0-9-]{0,40}$; planHash and blueprintHash each match ^[0-9a-f]{64}$. All three are required.

Error

{ "statusCode": 404, "error": "Not Found", "message": "..." }

The shape is open and none of the three fields is formally required, so a client should treat all three as optional and fall back to the HTTP status. The only structured error code on the Drops and Pacts surface is PACTS_REFERENCE_READ_ONLY, returned with 405.