{"openapi":"3.1.1","jsonSchemaDialect":"https://json-schema.org/draft/2020-12/schema","info":{"title":"BitUnlock API","version":"0.1.0","summary":"Payment-verified private delivery for Nostr stores","description":"BitUnlock is a deterministic hosted service for payment-verified private delivery. Every declared v1 operation is implemented and marked with x-bitunlock-availability metadata. Protected routes fail closed when required storage, identity, relay, credential, or receiving-wallet bindings are unavailable."},"servers":[{"url":"/","description":"The BitUnlock deployment serving this document"}],"tags":[{"name":"Discovery","description":"Public service identity and machine-readable contracts."},{"name":"Sellers","description":"Authenticated seller onboarding and product custody."},{"name":"Buyers","description":"Authenticated quotes, recovery, and private fulfillment."}],"paths":{"/health":{"get":{"operationId":"getHealth","summary":"Inspect service health and policy-signing state","tags":["Discovery"],"security":[],"x-bitunlock-availability":"available","responses":{"200":{"description":"The Worker is healthy and its policy configuration is valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/policy":{"get":{"operationId":"getPolicy","summary":"Discover the service policy","description":"Returns an explicit unsigned development document when completely unconfigured, or a signed NIP-78 envelope when production policy configuration is complete.","tags":["Discovery"],"security":[],"x-bitunlock-availability":"available","responses":{"200":{"description":"Development or signed service policy.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyResponse"}}}},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/.well-known/bitunlock.json":{"get":{"operationId":"getWellKnownPolicy","summary":"Discover the service policy at its well-known location","tags":["Discovery"],"security":[],"x-bitunlock-availability":"available","responses":{"200":{"description":"The same document returned by GET /policy.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyResponse"}}}},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/openapi.json":{"get":{"operationId":"getOpenApiDocument","summary":"Download this OpenAPI contract","tags":["Discovery"],"security":[],"x-bitunlock-availability":"available","responses":{"200":{"description":"Self-contained OpenAPI 3.1 JSON document.","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/tenants":{"post":{"operationId":"upsertTenant","summary":"Create or update the authenticated seller tenant","tags":["Sellers"],"security":[{"NostrNip98":[]}],"x-bitunlock-availability":"available","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantUpsertRequest"}}}},"responses":{"200":{"description":"Seller tenant state.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Tenant"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/InvalidInput"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/v1/wallet-connections":{"post":{"operationId":"createWalletConnection","summary":"Validate and encrypt a restricted seller NWC connection","tags":["Sellers"],"security":[{"NostrNip98":[]}],"x-bitunlock-availability":"available","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletConnectionCreateRequest"}}}},"responses":{"201":{"description":"Sanitized connection metadata. The NWC URI is never returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletConnection"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/InvalidInput"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/v1/products":{"post":{"operationId":"registerProduct","summary":"Register an encrypted delivery payload for a signed product","tags":["Sellers"],"security":[{"NostrNip98":[]}],"x-bitunlock-availability":"available","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductRegisterRequest"}}}},"responses":{"201":{"description":"Registered product metadata without delivery plaintext.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Product"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/InvalidInput"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/v1/products/{coord}/revoke":{"parameters":[{"$ref":"#/components/parameters/ProductCoordinate"}],"post":{"operationId":"revokeProduct","summary":"Revoke first-time fulfillment for a registered product","tags":["Sellers"],"security":[{"NostrNip98":[]}],"x-bitunlock-availability":"available","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductRevokeRequest"}}}},"responses":{"200":{"description":"Revoked product metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Product"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/InvalidInput"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/v1/quotes":{"post":{"operationId":"createQuote","summary":"Create an immutable payment plan for the authenticated buyer","tags":["Buyers"],"security":[{"NostrNip98":[]}],"x-bitunlock-availability":"available","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteCreateRequest"}}}},"responses":{"201":{"description":"Immutable three-leg payment plan.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentPlan"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/InvalidInput"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/v1/orders/{id}":{"parameters":[{"$ref":"#/components/parameters/OrderId"}],"get":{"operationId":"getOrder","summary":"Inspect authorized order and settlement state","tags":["Buyers"],"security":[{"NostrNip98":[]}],"x-bitunlock-availability":"available","responses":{"200":{"description":"Order state with secret-free payment metadata.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Order"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/v1/orders/{id}/refresh":{"parameters":[{"$ref":"#/components/parameters/OrderId"}],"post":{"operationId":"refreshOrder","summary":"Replace only expired and unpaid payment requests","tags":["Buyers"],"security":[{"NostrNip98":[]}],"x-bitunlock-availability":"available","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdempotentActionRequest"}}}},"responses":{"200":{"description":"Updated payment plan preserving settled legs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentPlan"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/v1/orders/{id}/unlock":{"parameters":[{"$ref":"#/components/parameters/OrderId"}],"post":{"operationId":"unlockOrder","summary":"Return the idempotent buyer-private delivery envelope","description":"Fails closed unless every required payment leg is authoritatively settled. Repeated authorized calls return the recorded envelope without charging again.","tags":["Buyers"],"security":[{"NostrNip98":[]}],"x-bitunlock-availability":"available","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdempotentActionRequest"}}}},"responses":{"200":{"description":"Previously recorded or newly created buyer fulfillment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Fulfillment"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}}},"components":{"securitySchemes":{"NostrNip98":{"type":"http","scheme":"Nostr","description":"Authorization: Nostr <base64 event>. BitUnlock requires a fresh kind 27235 event for every attempt, bound to exact URL, method, and raw-body SHA-256."}},"parameters":{"ProductCoordinate":{"name":"coord","in":"path","required":true,"description":"Percent-encoded kind 30078 Nostr product coordinate.","schema":{"$ref":"#/components/schemas/ProductCoordinate"}},"OrderId":{"name":"id","in":"path","required":true,"schema":{"$ref":"#/components/schemas/OrderId"}}},"responses":{"Unauthorized":{"description":"NIP-98 authentication failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"The authenticated pubkey does not own this resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"The resource was not found within the authenticated tenant scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Conflict":{"description":"The request conflicts with immutable or current state.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InvalidInput":{"description":"The authenticated request body failed validation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RateLimited":{"description":"The caller exceeded a bounded service quota.","headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"ServiceUnavailable":{"description":"A required policy, relay, wallet, database, or coordinator dependency is unavailable.","headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"HexPubkey":{"type":"string","pattern":"^[0-9a-f]{64}$"},"EventId":{"type":"string","pattern":"^[0-9a-f]{64}$"},"OrderId":{"type":"string","pattern":"^order_[A-Za-z0-9_-]{12,80}$"},"TenantId":{"type":"string","pattern":"^tenant_[A-Za-z0-9_-]{12,80}$"},"ProductCoordinate":{"type":"string","pattern":"^30078:[0-9a-f]{64}:[^:][^\\r\\n]{0,255}$"},"NostrEvent":{"type":"object","additionalProperties":false,"required":["id","pubkey","created_at","kind","tags","content","sig"],"properties":{"id":{"$ref":"#/components/schemas/EventId"},"pubkey":{"$ref":"#/components/schemas/HexPubkey"},"created_at":{"type":"integer","minimum":1},"kind":{"type":"integer","minimum":0,"maximum":65535},"tags":{"type":"array","maxItems":32,"items":{"type":"array","minItems":1,"maxItems":8,"items":{"type":"string","maxLength":4096}}},"content":{"type":"string","maxLength":131072},"sig":{"type":"string","pattern":"^[0-9a-f]{128}$"}}},"Health":{"type":"object","additionalProperties":false,"required":["schemaVersion","ok","service","protocolVersion","status","signedPolicy"],"properties":{"schemaVersion":{"const":1},"ok":{"type":"boolean"},"service":{"const":"bitunlock"},"protocolVersion":{"const":"seller-unlock-service-v1"},"status":{"enum":["development","active","deprecated","suspended","misconfigured"]},"signedPolicy":{"type":"boolean"},"servicePubkey":{"$ref":"#/components/schemas/HexPubkey"}}},"DevelopmentPolicy":{"type":"object","additionalProperties":false,"required":["schemaVersion","product","protocolVersion","status","signed","paymentAdapters","completionRule"],"properties":{"schemaVersion":{"const":1},"product":{"const":"BitUnlock"},"protocolVersion":{"const":"seller-unlock-service-v1"},"status":{"const":"development"},"signed":{"const":false},"paymentAdapters":{"type":"array","prefixItems":[{"const":"lightning-nwc"}],"items":false},"completionRule":{"const":"all"}}},"FeePolicy":{"type":"object","additionalProperties":false,"required":["policyVersion","feeBps","minimumSats","maximumSats","effectiveAt"],"properties":{"policyVersion":{"type":"string","minLength":1,"maxLength":64},"feeBps":{"type":"integer","minimum":0,"maximum":10000},"minimumSats":{"type":"integer","minimum":0},"maximumSats":{"type":"integer","minimum":0},"effectiveAt":{"type":"integer","minimum":1}}},"ServicePolicyDocument":{"type":"object","additionalProperties":false,"required":["schemaVersion","product","protocolVersions","policyVersion","status","endpoint","servicePubkey","policyCoordinate","paymentAdapters","completionRule","feePolicy","relays","effectiveAt"],"properties":{"schemaVersion":{"const":1},"product":{"const":"BitUnlock"},"protocolVersions":{"type":"array","prefixItems":[{"const":"seller-unlock-service-v1"}],"items":false},"policyVersion":{"type":"string","minLength":1,"maxLength":64},"status":{"enum":["active","deprecated","suspended"]},"endpoint":{"type":"string","format":"uri","pattern":"^https://"},"servicePubkey":{"$ref":"#/components/schemas/HexPubkey"},"policyCoordinate":{"type":"string","pattern":"^30078:[0-9a-f]{64}:bitunlock:service-policy:v1$"},"paymentAdapters":{"type":"array","items":{"enum":["lightning-nwc","mock"]},"minItems":1,"uniqueItems":true},"completionRule":{"const":"all"},"feePolicy":{"$ref":"#/components/schemas/FeePolicy"},"relays":{"type":"array","minItems":1,"uniqueItems":true,"items":{"type":"string","format":"uri","pattern":"^wss://"}},"effectiveAt":{"type":"integer","minimum":1}}},"SignedServicePolicy":{"type":"object","additionalProperties":false,"required":["schemaVersion","signed","document","event"],"properties":{"schemaVersion":{"const":1},"signed":{"const":true},"document":{"$ref":"#/components/schemas/ServicePolicyDocument"},"event":{"$ref":"#/components/schemas/NostrEvent"}}},"PolicyResponse":{"oneOf":[{"$ref":"#/components/schemas/DevelopmentPolicy"},{"$ref":"#/components/schemas/SignedServicePolicy"}]},"FeeCap":{"type":"object","additionalProperties":false,"required":["maximumFeeBps","maximumMinimumSats","maximumFeeSats"],"properties":{"maximumFeeBps":{"type":"integer","minimum":0,"maximum":10000},"maximumMinimumSats":{"type":"integer","minimum":0},"maximumFeeSats":{"type":"integer","minimum":0}}},"TenantUpsertRequest":{"type":"object","additionalProperties":false,"required":["acceptedPolicyCoordinate","feeCap","idempotencyKey"],"properties":{"acceptedPolicyCoordinate":{"type":"string","pattern":"^30078:[0-9a-f]{64}:bitunlock:service-policy:v1$"},"feeCap":{"$ref":"#/components/schemas/FeeCap"},"idempotencyKey":{"$ref":"#/components/schemas/IdempotencyKey"}}},"Tenant":{"type":"object","additionalProperties":false,"required":["tenantId","sellerPubkey","acceptedPolicyCoordinate","feeCap","status","createdAt","updatedAt"],"properties":{"tenantId":{"$ref":"#/components/schemas/TenantId"},"sellerPubkey":{"$ref":"#/components/schemas/HexPubkey"},"acceptedPolicyCoordinate":{"type":"string"},"feeCap":{"$ref":"#/components/schemas/FeeCap"},"status":{"enum":["pending_wallet","ready","suspended"]},"createdAt":{"type":"integer","minimum":1},"updatedAt":{"type":"integer","minimum":1}}},"WalletConnectionCreateRequest":{"type":"object","additionalProperties":false,"required":["label","nwcUri","idempotencyKey"],"properties":{"label":{"type":"string","minLength":1,"maxLength":80},"nwcUri":{"type":"string","minLength":32,"maxLength":4096,"writeOnly":true,"pattern":"^nostr\\+walletconnect://"},"idempotencyKey":{"$ref":"#/components/schemas/IdempotencyKey"}}},"WalletConnection":{"type":"object","additionalProperties":false,"required":["connectionId","label","adapter","status","capabilities","createdAt"],"properties":{"connectionId":{"type":"string","pattern":"^wallet_[A-Za-z0-9_-]{12,80}$"},"label":{"type":"string"},"adapter":{"const":"lightning-nwc"},"status":{"enum":["validating","ready","rejected","disabled"]},"capabilities":{"type":"array","uniqueItems":true,"items":{"enum":["make_invoice","lookup_invoice","get_info"]}},"createdAt":{"type":"integer","minimum":1}}},"ProductRegisterRequest":{"type":"object","additionalProperties":false,"required":["productCoordinate","policyCoordinate","claimEpoch","payloadType","sellerCiphertext","idempotencyKey"],"properties":{"productCoordinate":{"$ref":"#/components/schemas/ProductCoordinate"},"policyCoordinate":{"type":"string","pattern":"^30078:[0-9a-f]{64}:bitunlock:service-policy:v1$"},"claimEpoch":{"type":"integer","minimum":1},"payloadType":{"enum":["claim-url","license-key","json"]},"sellerCiphertext":{"type":"string","minLength":1,"maxLength":131072,"writeOnly":true},"idempotencyKey":{"$ref":"#/components/schemas/IdempotencyKey"}}},"ProductRevokeRequest":{"type":"object","additionalProperties":false,"required":["claimEpoch","idempotencyKey"],"properties":{"claimEpoch":{"type":"integer","minimum":1},"reason":{"type":"string","maxLength":280},"idempotencyKey":{"$ref":"#/components/schemas/IdempotencyKey"}}},"Product":{"type":"object","additionalProperties":false,"required":["productCoordinate","sellerPubkey","policyCoordinate","claimEpoch","payloadType","status","createdAt","updatedAt"],"properties":{"productCoordinate":{"$ref":"#/components/schemas/ProductCoordinate"},"sellerPubkey":{"$ref":"#/components/schemas/HexPubkey"},"policyCoordinate":{"type":"string"},"claimEpoch":{"type":"integer","minimum":1},"payloadType":{"enum":["claim-url","license-key","json"]},"status":{"enum":["active","revoked"]},"createdAt":{"type":"integer","minimum":1},"updatedAt":{"type":"integer","minimum":1}}},"IdempotencyKey":{"type":"string","pattern":"^[A-Za-z0-9_-]{16,128}$"},"IdempotentActionRequest":{"type":"object","additionalProperties":false,"required":["idempotencyKey"],"properties":{"idempotencyKey":{"$ref":"#/components/schemas/IdempotencyKey"}}},"QuoteCreateRequest":{"type":"object","additionalProperties":false,"required":["productCoordinate","buyerPubkey","idempotencyKey"],"properties":{"productCoordinate":{"$ref":"#/components/schemas/ProductCoordinate"},"buyerPubkey":{"$ref":"#/components/schemas/HexPubkey"},"idempotencyKey":{"$ref":"#/components/schemas/IdempotencyKey"}}},"FeeAllocation":{"type":"object","additionalProperties":false,"required":["sellerSats","bitunlockSats","totalSats"],"properties":{"sellerSats":{"type":"integer","minimum":0},"bitunlockSats":{"type":"integer","minimum":0},"totalSats":{"type":"integer","minimum":1}}},"PaymentLeg":{"type":"object","additionalProperties":false,"required":["role","amountSats","rail","adapter","paymentRequest","paymentHash","status","expiresAt"],"properties":{"role":{"enum":["seller","bitunlock"]},"amountSats":{"type":"integer","minimum":1},"rail":{"enum":["lightning","sandbox"]},"adapter":{"enum":["lightning-nwc","mock"]},"paymentRequest":{"type":"string","minLength":1},"paymentHash":{"type":"string","pattern":"^[0-9a-f]{64}$"},"status":{"enum":["pending","settled","expired"]},"expiresAt":{"type":"integer","minimum":1}}},"PaymentPlan":{"type":"object","additionalProperties":false,"required":["schemaVersion","protocolVersion","orderId","productCoordinate","buyerPubkey","currency","totalSats","completionRule","feeSnapshot","legs"],"properties":{"schemaVersion":{"const":1},"protocolVersion":{"const":"seller-unlock-service-v1"},"orderId":{"$ref":"#/components/schemas/OrderId"},"productCoordinate":{"$ref":"#/components/schemas/ProductCoordinate"},"buyerPubkey":{"$ref":"#/components/schemas/HexPubkey"},"currency":{"const":"SAT"},"totalSats":{"type":"integer","minimum":1},"completionRule":{"const":"all"},"feeSnapshot":{"type":"object","additionalProperties":false,"required":["serviceFeePolicy","allocation"],"properties":{"serviceFeePolicy":{"$ref":"#/components/schemas/FeePolicy"},"allocation":{"$ref":"#/components/schemas/FeeAllocation"}}},"legs":{"type":"array","minItems":2,"maxItems":2,"items":{"$ref":"#/components/schemas/PaymentLeg"}}}},"Order":{"type":"object","additionalProperties":false,"required":["orderId","productCoordinate","buyerPubkey","state","paymentPlan","createdAt","updatedAt"],"properties":{"orderId":{"$ref":"#/components/schemas/OrderId"},"productCoordinate":{"$ref":"#/components/schemas/ProductCoordinate"},"buyerPubkey":{"$ref":"#/components/schemas/HexPubkey"},"state":{"enum":["created","quoted","partially_paid","paid","fulfilled","expired_pending_requote","cancelled","revoked"]},"paymentPlan":{"$ref":"#/components/schemas/PaymentPlan"},"createdAt":{"type":"integer","minimum":1},"updatedAt":{"type":"integer","minimum":1}}},"Fulfillment":{"type":"object","additionalProperties":false,"required":["schemaVersion","orderId","productCoordinate","buyerPubkey","claimEpoch","buyerEnvelope","fulfilledAt"],"properties":{"schemaVersion":{"const":1},"orderId":{"$ref":"#/components/schemas/OrderId"},"productCoordinate":{"$ref":"#/components/schemas/ProductCoordinate"},"buyerPubkey":{"$ref":"#/components/schemas/HexPubkey"},"claimEpoch":{"type":"integer","minimum":1},"buyerEnvelope":{"type":"string","minLength":1,"maxLength":131072},"fulfillmentEvent":{"$ref":"#/components/schemas/NostrEvent"},"fulfilledAt":{"type":"integer","minimum":1}}},"Error":{"type":"object","additionalProperties":false,"required":["error"],"properties":{"error":{"type":"object","additionalProperties":false,"required":["code","message"],"properties":{"code":{"type":"string","pattern":"^[a-z][a-z0-9_]{2,63}$"},"message":{"type":"string","minLength":1,"maxLength":280}}}}}}}}