# blocksign.red — Complete API Reference > Blockchain-anchored e-signatures. One API call to create, send, and verify contracts. This is the full API reference for blocksign.red. For a quick overview, see /llms.txt. --- ## Authentication All authenticated endpoints require one of: - API Key: `Authorization: Bearer bsk_live_...` or `Authorization: Bearer bsk_agent_...` - JWT: `Authorization: Bearer eyJ...` - Workflow token (negotiation only): `x-workflow-token: bsk_wft_...` OAuth login is available via Google and Microsoft. Accounts are auto-created on first social login. The OAuth flow is handled by the frontend; the API provides a server-to-server exchange endpoint. ### Agent Keys (bsk_agent_*) Agent keys are scoped with capabilities (deny-by-default): - `agreement.create` — create agreements and envelopes - `agreement.read` — read agreement/envelope status - `agreement.void` — void envelopes - `template.use` — use contract templates - `template.create` — create custom templates - `document.upload` — upload documents - `billing.auto_purchase` — auto-buy the 10-credit pack when quota exhausted (requires payment method on file) Human JWT and `bsk_live_*` keys have all capabilities implicitly. ### Create API Key ``` POST /v1/api-keys Authorization: Bearer Content-Type: application/json { "name": "My Agent", "is_agent_key": true, "capabilities": ["agreement.create", "agreement.read", "template.use"], "auto_purchase_credits": false } ``` Response: ```json { "id": "uuid", "key": "bsk_agent_...", "name": "My Agent", "capabilities": ["agreement.create", "agreement.read", "template.use"], "created_at": "2026-05-15T00:00:00Z" } ``` ### Auth Endpoints - `POST /v1/auth/sign-up` — create account - `POST /v1/auth/sign-in` — get JWT tokens - `POST /v1/auth/oauth/exchange` — server-to-server OAuth token exchange. Called by the frontend Auth.js after completing an OAuth flow with Google or Microsoft. Accepts `{ provider, provider_account_id, email, name, email_verified }` with an `X-Internal-Secret` header. Returns the same auth response as sign-in. - `POST /v1/auth/verify-email` — verify email with OTP - `POST /v1/auth/resend-verification` - `POST /v1/auth/mfa/setup`, `/mfa/confirm`, `/mfa/verify`, `DELETE /mfa/disable` --- ## Documents ### POST /v1/documents Upload a document. Multipart form-data. Accepted MIME types: `application/pdf`, `text/plain`, `text/markdown`. Maximum 40 pages. For `text/plain` and `text/markdown`: blocksign converts the content to a proper multi-page US Letter PDF and stores the source text for subsequent AI field detection. Fields: - `file` (required) — PDF bytes, plain text, or Markdown - `title` (optional) — defaults to filename - `detect_fields` (optional) — `"true"` to run AI field detection and include results in the response - `signers_count` (optional, integer, default 1) — number of signers, used as context for field detection ``` POST /v1/documents Authorization: Bearer bsk_live_... Content-Type: multipart/form-data file: title: "My Contract" detect_fields: "true" signers_count: 2 ``` Normal response: ```json { "id": "uuid", "title": "My Contract", "filename": "contract.pdf", "source_sha256_hex": "abc123...", "byte_length": 102400, "page_count": 5, "mime_type": "application/pdf" } ``` With `detect_fields=true`, the response also includes: ```json { "id": "uuid", "title": "My Contract", "source_sha256_hex": "abc123...", "byte_length": 102400, "page_count": 5, "mime_type": "application/pdf", "detected_fields": [ { "field_type": "signature", "page": 2, "x": 0.10, "y": 0.84, "w": 0.35, "h": 0.04, "signer_index": 0, "confidence": 0.93, "source": "ai" }, { "field_type": "date", "page": 2, "x": 0.48, "y": 0.84, "w": 0.20, "h": 0.04, "signer_index": 0, "confidence": 0.90, "source": "ai" } ] } ``` `source` values: `"ai"` (Anthropic claude-haiku), `"heuristic"` (regex), `"default"` (per-signer fallback). ### GET /v1/documents/:id Fetch document metadata. Returns same shape as POST response (without `detected_fields`). --- ## Agent Agreements (One-Call Flow) The recommended approach for agents. One call replaces the traditional multi-step flow (upload, create envelope, add signers, send). ### POST /v1/agent/agreements Four input modes — mutually exclusive. **Mode 1: Template** No PDF needed. Blocksign interpolates the template, renders a PDF, and sends for signing. ``` POST /v1/agent/agreements Authorization: Bearer bsk_agent_... Content-Type: application/json { "template": "nda", "variables": { "party_a_name": "Acme Corp", "party_a_email": "alice@acme.com", "party_b_name": "Bob Smith", "party_b_email": "bob@example.com", "effective_date": "2026-05-15", "jurisdiction": "Delaware", "confidentiality_period_years": 2 }, "options": { "auto_send": true, "routing_mode": "parallel", "expires_in_days": 14, "webhook_url": "https://agent.example.com/cb" } } ``` **Mode 2: Text/Markdown (NEW)** Pass contract text directly. Blocksign converts it to PDF and runs AI field detection automatically. ```json { "document_text": "# Services Agreement\n\nThis agreement is between {{party_a}} and {{party_b}}...\n\nSignature: _______\nDate: _______", "document_text_format": "markdown", "document_title": "Services Agreement", "signers": [ { "name": "Alice", "email": "alice@acme.com", "fields": "auto" }, { "name": "Bob", "email": "bob@example.com", "fields": "auto" } ], "options": { "auto_send": true } } ``` `document_text_format`: `"markdown"` or `"plain"`. **Mode 3: PDF base64** Bring your own PDF, encoded as base64. ```json { "document_base64": "JVBERi0xLjQK...", "document_title": "My Agreement", "signers": [ { "name": "Alice", "email": "alice@acme.com", "fields": [ { "field_type": "signature", "page": 1, "x": 0.1, "y": 0.1, "w": 0.3, "h": 0.05 } ] }, { "name": "Bob", "email": "bob@example.com", "fields": "auto" } ] } ``` **Mode 4: Pre-uploaded document** Reference a document already uploaded via POST /v1/documents. ```json { "document_id": "uuid", "document_title": "My Agreement", "signers": [ { "name": "Alice", "email": "alice@acme.com", "fields": "auto" } ] } ``` **Per-signer `fields` values:** - Array of explicit field objects — `[{ "field_type": "signature", "page": 1, "x": 0.1, "y": 0.84, "w": 0.35, "h": 0.04 }]` - `"auto"` — run 3-tier AI detection (claude-haiku → regex heuristics → per-signer defaults) - Omit entirely — one default signature field per signer **Agent-to-agent handoff (optional per signer):** When `agent_callback_url` or `agent_mcp_url` is set for a signer, blocksign dispatches a workflow token (`bsk_wft_*`) to the counterparty agent. The token is scoped to the envelope and has a 72h TTL. ```json { "name": "Bob", "email": "bob@example.com", "agent_callback_url": "https://bob-agent.example.com/callback", "agent_mcp_url": "https://bob-agent.example.com/mcp" } ``` Delivery method: HTTP POST to `agent_callback_url`, or MCP `tools/call` with method `agreement_review_requested` to `agent_mcp_url`. **Response** (201 Created): ```json { "agreement_id": "uuid", "envelope_id": "uuid", "status": "sent", "verification_url": "https://blocksign.red/verify/uuid", "signers": [ { "name": "Alice", "email": "alice@acme.com", "status": "sent", "signing_url": "https://blocksign.red/sign/tok_abc123" }, { "name": "Bob", "email": "bob@example.com", "status": "sent", "signing_url": "https://blocksign.red/sign/tok_def456" } ] } ``` ### GET /v1/agent/agreements/:id Unified status view: envelope state, signer progress, envelope ID, and verification URL. ``` GET /v1/agent/agreements/uuid Authorization: Bearer bsk_agent_... ``` Response: ```json { "agreement_id": "uuid", "envelope_id": "uuid", "status": "completed", "title": "Mutual NDA", "created_at": "2026-05-15T10:00:00Z", "signers": [ { "name": "Alice", "email": "alice@acme.com", "status": "signed", "routing_order": 1 } ], "verification_url": "https://blocksign.red/verify/uuid" } ``` ### GET /v1/agent/agreements/:id/access Get a presigned download URL for a completed agreement. Returns 200 with `download_url: null` if not yet completed. ``` GET /v1/agent/agreements/uuid/access Authorization: Bearer bsk_agent_... ``` Response: ```json { "agreement_id": "uuid", "status": "completed", "title": "Mutual NDA", "verification_url": "https://blocksign.red/verify/uuid", "download_url": "https://s3.example.com/...", "download_expires_at": "2026-05-24T10:00:00Z", "signers": [ { "name": "Alice", "email": "alice@acme.com", "status": "signed", "signed_at": "2026-05-15T12:00:00Z" } ], "blockchain_anchor": { "chain": "base", "tx_hash": "0x..." }, "audit_chain_tip": "abc123..." } ``` `download_url` is a 24-hour presigned S3 URL. --- ## Agent Negotiation Counterparty agents can submit counter-proposals and accept terms using a `bsk_wft_*` workflow token or a full API key. Workflow token is passed as: `x-workflow-token: bsk_wft_...` ### POST /v1/agent/agreements/:id/counter Submit a revised version of the agreement. ```json { "body_markdown": "# Updated Terms\n\n...", "variables": { "confidentiality_period_years": 1 }, "message": "Reduced term to 1 year" } ``` Response: ```json { "envelope_id": "uuid", "version": 2, "status": "pending", "message": "Counter-proposal submitted" } ``` ### GET /v1/agent/agreements/:id/history Returns all proposal versions in reverse chronological order. ```json { "envelope_id": "uuid", "versions": [ { "version": 2, "proposed_by": "bob@example.com", "body_markdown": "# Updated Terms\n\n...", "variables": { "confidentiality_period_years": 1 }, "message": "Reduced term to 1 year", "status": "pending", "created_at": "2026-05-15T13:00:00Z" } ] } ``` ### POST /v1/agent/agreements/:id/accept Accept the current version of the terms. After acceptance, proceed to signing via `POST /v1/envelopes/:id/send`. ```json { "agreement_id": "uuid", "status": "accepted", "message": "Terms accepted. Use POST /v1/envelopes/:id/send to proceed to signing." } ``` --- ## AI Field Detection ### POST /v1/agent/fields/detect Run AI field detection on a previously uploaded text document (plain text or Markdown). Returns field placement suggestions without creating an agreement. ``` POST /v1/agent/fields/detect Authorization: Bearer bsk_agent_... Content-Type: application/json { "document_id": "uuid", "signers_count": 2 } ``` Response: ```json { "document_id": "uuid", "fields": [ { "field_type": "signature", "page": 2, "x": 0.10, "y": 0.72, "w": 0.35, "h": 0.04, "signer_index": 0, "confidence": 0.92, "source": "ai" }, { "field_type": "date", "page": 2, "x": 0.48, "y": 0.72, "w": 0.20, "h": 0.04, "signer_index": 0, "confidence": 0.90, "source": "ai" } ], "detection_source": "ai", "model_used": "claude-haiku-4-5-20251001" } ``` ### 3-Tier Detection System Field detection always returns results — it never fails silently. 1. **AI** — Anthropic claude-haiku reads contract text, returns JSON field hints with `line_hint` matched to PDF coordinates via layout tracking. Confidence ~0.90. 2. **Heuristic** — regex patterns: `_{4,}`, `[SIGN HERE]`, `(?i)signature`, `(?i)date[d]?\s*[:\-]+\s*_{2,}`, `(?i)initials?`. Confidence 0.70–0.75. 3. **Default** — one signature field per signer at `(x=0.10, y=0.85 - signer_index*0.08, w=0.35, h=0.04)` on page 1. Confidence 0.30. `source` in each field indicates which tier produced it: `"ai"`, `"heuristic"`, or `"default"`. --- ## Envelopes (Traditional Flow) Use envelopes directly when you need full control over field placement and routing configuration. ### POST /v1/envelopes ``` POST /v1/envelopes Authorization: Bearer bsk_live_... Content-Type: application/json { "document_id": "uuid", "title": "Services Agreement", "routing_mode": "sequential", "auth_level_required": "email", "language": "en", "expires_in_days": 30, "signers": [ { "client_ref": "signer1", "email": "alice@example.com", "name": "Alice", "routing_order": 1, "locale": "en", "auth_methods": ["email"] } ], "fields": [ { "signer_ref": "signer1", "page": 1, "x": 0.1, "y": 0.1, "w": 0.3, "h": 0.05, "field_type": "signature", "required": true, "label": "Signature" } ] } ``` Field coordinates: normalized [0,1]. Origin is bottom-left of the PDF page. Response: ```json { "envelope": { "id": "uuid", "status": "draft" }, "signers": [ { "signer_id": "uuid", "client_ref": "signer1", "email": "alice@example.com", "signing_token": "tok_...", "signing_url": "https://blocksign.red/sign/tok_..." } ] } ``` ### GET /v1/envelopes Query params: `?status=draft&limit=20&offset=0` ### GET /v1/envelopes/:id ### POST /v1/envelopes/:id/send Dispatches signing invitations to all signers. Requires `Idempotency-Key` header. ### POST /v1/envelopes/:id/void Voids an active envelope. Cannot be undone. --- ## Signing Ceremony These endpoints are called by signers via their unique token. ### GET /v1/sign/:token Load the signing session. Returns document URL, fields to fill, and signer info. ### POST /v1/sign/:token/consent Record that the signer has reviewed and consents to sign. ### POST /v1/sign/:token/fields Submit filled field values. ```json { "fields": [ { "field_id": "uuid", "value": "2026-05-15" } ] } ``` ### POST /v1/sign/:token/sign Apply the cryptographic signature. Finalizes the signer's participation. --- ## Verification (No Auth Required) ### GET /v1/verify/:envelope_id Anyone can verify document integrity without an account. The response includes the stored audit chain tip and the recomputed tip — if they match, the document is untampered. Response: ```json { "envelope_id": "uuid", "status": "verified", "event_count": 8, "event_chain_tip_sha256_hex": "abc123...", "computed_tip_sha256_hex": "abc123...", "anchors": [ { "chain": "base", "status": "confirmed", "tx_hash_hex": "0x...", "block_number": 12345678 } ] } ``` --- ## Webhooks ### POST /v1/webhook-endpoints Register a URL to receive webhook events. ```json { "url": "https://example.com/webhooks/blocksign", "events": ["envelope.sent", "signer.signed", "envelope.completed", "envelope.anchored"] } ``` All webhook deliveries include an HMAC signature in the `svix-signature` header. ### Webhook Events - `envelope.sent` — envelope dispatched to signers - `signer.opened` — signer viewed the document - `signer.signed` — signer completed signing - `envelope.completed` — all signers finished - `envelope.anchored` — blockchain confirmation received - `envelope.voided` — envelope was voided --- ## Templates Contract templates allow agents to generate agreements without uploading a PDF. Templates use Markdown with `{{variable}}` placeholders and a JSON Schema defining required variables. ### GET /v1/templates List available templates (your org's custom templates + platform public templates). Requires capability: `template.use` Response: ```json [ { "id": "uuid", "slug": "nda", "version": 1, "title": "Mutual Non-Disclosure Agreement", "category": "legal", "is_public": true, "org_id": null, "created_at": "2026-05-16T00:00:00Z" } ] ``` ### GET /v1/templates/:id_or_slug Get template details including body markdown and variables schema. Accepts UUID or slug. Requires capability: `template.use` ### POST /v1/templates Create a custom org-scoped template. Requires capability: `template.create` ```json { "slug": "my-nda", "title": "Custom NDA", "category": "legal", "body_markdown": "# NDA\n\nBetween {{party_a}} and {{party_b}}...", "variables_schema": { "type": "object", "required": ["party_a", "party_b"], "properties": { "party_a": { "type": "string" }, "party_b": { "type": "string" } } }, "is_public": false } ``` ### PUT /v1/templates/:id Update a custom template (org-owned only; platform templates cannot be modified). ### DELETE /v1/templates/:id Delete a custom template. ### POST /v1/templates/:slug/preview Preview a template with interpolated variables. No PDF is generated. ```json { "variables": { "party_a_name": "Acme Corp", "party_b_name": "Bob Smith", "effective_date": "2026-05-16", "jurisdiction": "Delaware", "confidentiality_period_years": 2 } } ``` Response: ```json { "title": "Mutual Non-Disclosure Agreement", "rendered_markdown": "# Mutual Non-Disclosure Agreement\n\n...Acme Corp...Bob Smith..." } ``` ### Built-in Platform Templates - `nda` — Mutual Non-Disclosure Agreement - `services-agreement` — Professional Services Agreement - `employment-offer` — Employment Offer Letter - `contractor` — Independent Contractor Agreement - `sales-agreement` — Simple Sales Agreement --- ## Billing ### GET /v1/billing/status Check current plan, usage, and credit balance. ### POST /v1/billing/checkout Start a Stripe Checkout session for a subscription upgrade. ```json { "plan": "pro" } ``` ### POST /v1/billing/credits/purchase Purchase envelope credits. Valid packs: 10 ($12), 50 ($50), 200 ($160). Credits never expire. ```json { "credits": 50 } ``` If a payment method is on file, charges immediately and returns: ```json { "credits_added": 50, "balance": 73, "payment_intent_id": "pi_..." } ``` Otherwise returns a Stripe Checkout URL: ```json { "checkout_url": "https://checkout.stripe.com/...", "session_id": "cs_..." } ``` ### POST /v1/billing/portal Get a Stripe customer portal URL for managing payment methods and subscriptions. ```json { "portal_url": "https://billing.stripe.com/..." } ``` ### 402 Payment Required When payment is needed, the API returns HTTP 402 with structured, agent-parsable instructions including per-document cost: ```json { "error": "payment_required", "message": "Payment required (0/0 envelopes this month, 0 credits remaining)", "billing_status": { "plan": "free", "envelopes_used": 0, "envelopes_limit": 0, "credits_remaining": 0 }, "actions": [ { "type": "pay_now", "api": "POST /v1/billing/charge", "document_cost": { "pages": 15, "amount_cents": 549, "breakdown": "$2.99 base + 5 pages × $0.50" } }, { "type": "buy_credits", "api": "POST /v1/billing/credits/purchase", "packs": [ { "credits": 10, "price_usd": 12 }, { "credits": 50, "price_usd": 50 }, { "credits": 200, "price_usd": 160 } ] }, { "type": "upgrade", "api": "POST /v1/billing/checkout", "plans": [ { "plan": "pro", "price_usd": 29, "envelopes": 100 }, { "plan": "business", "price_usd": 79, "envelopes": 500 } ] } ] } ``` ### Per-Document Pricing $2.99 base for documents up to 10 pages, plus $0.50 per page over 10. Maximum 40 pages per document. | Pages | Cost | |-------|------| | 1-10 | $2.99 | | 15 | $5.49 | | 20 | $7.99 | | 40 | $17.99 | ### GET /v1/billing/status Returns current plan, usage, credits, and per-document pricing: ```json { "plan": "free", "envelopes_used": 3, "envelopes_limit": 0, "credits_remaining": 7, "has_payment_method": true, "per_document_pricing": { "base_cents": 299, "per_page_over_10_cents": 50, "description": "$2.99 base (≤10 pages) + $0.50/page over 10" } } ``` ### POST /v1/billing/charge Charge per-document price for a specific envelope. Requires a card on file (Stripe customer). ```json POST /v1/billing/charge { "envelope_id": "uuid" } → { "status": "charged", "amount_cents": 549, "pages": 15, "breakdown": "$2.99 base + 5 pages × $0.50" } ``` Agent keys with the `billing.auto_purchase` capability and a card on file never receive a 402. The smallest credit pack is charged automatically when quota is exhausted. ### Agent Payment Flow Step-by-step guide for AI agents handling payment: 1. **Before creating an agreement**, optionally check `GET /v1/billing/status` to see if you have credits or quota remaining. 2. **If you receive HTTP 402**, parse the JSON response: - `billing_status` — current plan, usage, credits - `actions` — array of options, each with `type` and `api` endpoint 3. **Choose a payment method:** **Option A — Pay per-document (recommended for occasional use):** ``` POST /v1/billing/charge { "envelope_id": "" } ``` Charges the card on file. Amount is calculated from document page count. **Option B — Buy credits (recommended for batch operations):** ``` POST /v1/billing/credits/purchase { "credits": 50 } ``` Credits are flat-rate (1 credit = 1 envelope regardless of pages). Never expire. **Option C — Subscribe (recommended for high volume):** ``` POST /v1/billing/checkout { "plan": "pro" } ``` Returns a Stripe Checkout URL. After subscription activates, quota resets monthly. 4. **Retry the original request** after payment succeeds. 5. **Auto-purchase shortcut**: Create your agent key with `billing.auto_purchase` capability and ensure a card is on file. The API will auto-buy the smallest credit pack (10 credits/$12) when quota is exhausted — your agent never sees a 402. --- ## Field Types | Type | Description | Default Size (w x h) | |-------------|--------------------------|----------------------| | `signature` | Drawn or typed signature | 0.35 x 0.04 | | `initials` | Signer's initials | 0.10 x 0.04 | | `text` | Free-text input | 0.20 x 0.03 | | `date` | Date picker | 0.20 x 0.04 | | `checkbox` | Boolean checkbox | 0.03 x 0.03 | Coordinates are normalized [0,1]. Origin is bottom-left of the PDF page. --- ## Rate Limits - Auth endpoints: 20 requests / 60 seconds (per IP) - Signing ceremony: 60 requests / 60 seconds (per IP) - API writes: 120 requests / 60 seconds (per org) Rate-limited responses return HTTP 429 with `Retry-After` header. --- ## Idempotency For POST endpoints that modify state, include an `Idempotency-Key` header: ``` Idempotency-Key: my-unique-request-id-123 ``` Duplicate requests within 24 hours return the cached response with `x-idempotency-replay: hit`. Required on `POST /v1/envelopes/:id/send`. --- ## Error Format All errors return JSON: ```json { "error_code": "validation_failed", "message": "signers: must have at least 1 item" } ``` Error codes: `not_found`, `unauthorized`, `forbidden`, `mfa_required`, `email_unverified`, `conflict`, `validation_failed`, `rate_limited`, `payment_required`, `internal_error` --- ## Anonymous Prepare Flow (Web UI) The `/prepare` page allows users to send documents for signing without creating an account first. The entire upload and field placement workflow runs client-side (no server calls until payment). ### Flow 1. **Upload PDF** (client-side) — validates file type, 25 MB size limit, and 40-page limit using pdfjs. Creates a blob URL for the PDF viewer. 2. **Place Fields** (client-side) — interactive field placement on the PDF. Supports signature, initials, text, date, checkbox, radio, dropdown, and attachment field types. Multiple signers with color-coded fields. 3. **Review & Pay** — shows document summary, signer list, price breakdown, envelope title, and routing mode. Two payment options: - **Pay per document** — Stripe Checkout for a one-time charge ($2.99 base + $0.50/page over 10) - **Subscribe** — Pro ($29/mo, 100 docs) or Business ($79/mo, 500 docs) 4. **Stripe Checkout** — before redirecting to Stripe, all state (PDF bytes, fields, signers, title, routing mode) is saved to IndexedDB. After payment, Stripe redirects back to `/prepare?session_id={CHECKOUT_SESSION_ID}`. 5. **Session Exchange** — the frontend calls `GET /api/prepare/session?checkout_session_id=...` which: - Verifies the Stripe checkout session is paid - Extracts customer email from the Stripe session - Creates or finds the user account via `POST /v1/auth/oauth/exchange` - Sets a `blocksign-prepare-token` cookie for authenticated API access 6. **Auto-Send** — restores state from IndexedDB, uploads the PDF via the authenticated proxy, creates the envelope with fields and signers, sends it, and displays signing URLs. ### Cancel Flow If the user cancels Stripe Checkout, they're redirected to `/prepare?canceled=true`. The page restores state from IndexedDB and shows a dismissible "Payment was canceled" banner. ### Frontend API Routes (No Auth Required) - `POST /api/prepare/checkout` — creates a Stripe Checkout Session. Accepts `{ pageCount, mode: "one_shot" | "subscription", plan?: "pro" | "business" }`. Returns `{ url, sessionId }`. - `GET /api/prepare/session?checkout_session_id=cs_xxx` — exchanges a paid Stripe checkout session for an authenticated session. Returns `{ ok, userId, orgId, region }` and sets a `blocksign-prepare-token` cookie. ### Per-Document Pricing | Pages | Cost | |-------|------| | 1-10 | $2.99 | | 11 | $3.49 | | 15 | $5.49 | | 20 | $7.99 | | 40 | $17.99 | --- ## Discovery Endpoints (No Auth) - `GET /llms.txt` — capability summary - `GET /llms-full.txt` — this document - `GET /.well-known/mcp.json` — MCP server discovery - `GET /v1/agent/instructions` — structured JSON instructions for agents - `GET /v1/openapi.json` — OpenAPI 3.1 spec --- ## MCP Server For AI agents using the Model Context Protocol. **Transport:** Stateless HTTP JSON-RPC (MCP spec 2024-11-05) **Endpoint:** https://mcp.blocksign.red/mcp **Discovery:** GET https://mcp.blocksign.red/.well-known/mcp.json **Auth:** `Authorization: Bearer bsk_agent_*` on every request ### Tools (11) - `create_agreement` — POST /v1/agent/agreements (all four input modes supported) - `get_agreement_status` — GET /v1/agent/agreements/:id - `list_agreements` — GET /v1/envelopes - `list_templates` — GET /v1/templates - `verify_agreement` — GET /v1/verify/:id - `void_agreement` — POST /v1/envelopes/:id/void - `preview_template` — POST /v1/templates/:slug/preview - `upload_document` — accepts `text_content`, `format` ("plain"|"markdown"), `title`, `detect_fields`, `signers_count`; POSTs to /v1/documents as multipart/form-data - `detect_fields` — `{ document_id, signers_count }` → POST /v1/agent/fields/detect - `check_billing_status` — GET /v1/billing/status (returns plan, usage, credits, per-document pricing, payment method status) - `purchase_credits` — POST /v1/billing/credits/purchase `{ credits: 10|50|200 }` (buy credit packs, charges card on file or returns checkout URL) ### Resources - `agreement://{id}` — live agreement state - `template://{slug}` — template definition - `verification://{id}` — public verification result - `templates://catalog` — all available templates ### Prompts - `create_nda` — guided NDA creation flow - `review_status` — check and summarize agreement status - `explain_verification` — explain what a verification result means