# Crane Ledger API - LLM Reference > This file provides a structured overview of the Crane Ledger API for AI assistants and language models. Last updated: 2026-08-12 ## Overview Crane Ledger is a headless double-entry accounting **ledger of record**. AI tools (ChatGPT, Claude, Copilot, Gemini, Perplexity, Grok, Cursor, etc.) act as the generative UI over MCP or REST. Multi-organization accounting with credit-based billing. Pricing + agent onboarding: https://craneledger.ai/pricing.md Human docs: https://craneledger.ai/docs Quick Start: https://craneledger.ai/docs/getting-started/quick-start Connect your AI (hub): https://craneledger.ai/docs/connect/overview ChatGPT: https://craneledger.ai/docs/connect/chatgpt Claude: https://craneledger.ai/docs/connect/claude GitHub Copilot: https://craneledger.ai/docs/connect/github-copilot Perplexity: https://craneledger.ai/docs/connect/perplexity Any MCP client: https://craneledger.ai/docs/connect/any-mcp-client ## Base URL ``` https://api.craneledger.ai ``` ## Agent bootstrap (register → key → credits → MCP) MCP and most REST routes require a Bearer token. **Bootstrap without a key:** ```http POST https://api.craneledger.ai/accounts/master Content-Type: application/json {"name":"Agent Org","base_currency_code":"USD"} ``` Response includes `organization_id`, one-time `api_key` (`ha_live_…`), and **500 free credits** on the master org. Save the key immediately. Then authenticate every request: ``` Authorization: Bearer ha_live_… ``` Load more credits: - Stripe checkout: `POST /organizations/{master_id}/credits/purchase` (returns `checkout_url`) - x402 USDC on Base: `POST /organizations/{master_id}/credits/purchase-x402?credits=1000` (agents without a browser) - MCP: `purchase_credits`, `start_x402_credit_purchase` / `complete_x402_credit_purchase` Connect MCP: ``` POST https://api.craneledger.ai/mcp Authorization: Bearer ha_live_… ``` ChatGPT directory / custom connector (no credit purchase tools): ``` POST https://api.craneledger.ai/mcp/chatgpt Authorization: Bearer ha_live_… ``` Product `/mcp` keeps `purchase_credits`, `start_x402_credit_purchase`, and `complete_x402_credit_purchase`. `/mcp/chatgpt` hides those three. Same OAuth 2.1 on both. Do **not** call MCP `create_master_account` before you have a key — use REST `/accounts/master` first. Optional human dashboard user: `POST /users` with `{ "provider", "provider_subject", "email?", "name?" }` then pass `user_id` on master create. Headless agents can omit `user_id`. ## Human dashboard sign-in https://craneledger.ai/auth/signin — any of: - Continue with GitHub - Continue with Google - Continue with Apple - Email me a sign-in link (passwordless) First login creates a master org + 500 credits. Different providers = separate accounts even with the same email. Then use OAuth consent for Claude/ChatGPT connectors. Humans can also sign up at https://craneledger.ai and use OAuth consent for Claude/ChatGPT connectors. ## Human support (no GitHub required) Customers open tickets in the dashboard (**Support** tab). Backend storage is GitHub Issues via a bot PAT; tickets are keyed by `submitter:USR_…` labels so Google/Apple/email users work without a GitHub account. Humans never need repo access. ## Authentication Crane Ledger supports **OAuth 2.1** (MCP connectors) and **static API keys**. All authenticated requests use: ``` Authorization: Bearer ``` ### OAuth 2.1 (recommended for Claude/ChatGPT MCP) - Protected resource metadata: `GET https://api.craneledger.ai/.well-known/oauth-protected-resource` - Authorization server: `https://auth.craneledger.ai` (RFC 8414 at `/.well-known/oauth-authorization-server`) - MCP resource audience: `https://api.craneledger.ai/mcp` - Scopes: `ledger:read`, `ledger:write`, `ledger:admin` - Unauthenticated `/mcp` returns `401` with `WWW-Authenticate: Bearer resource_metadata="..."` - Consent UI: `https://craneledger.ai/oauth/consent` (any dashboard sign-in method) ### Static API keys API keys are prefixed with: - `ha_live_` - Production environment - `ha_test_` - Test/development environment Keys grant full org-scoped access (no OAuth scope restrictions). ## Core Resources ### Organizations - `POST /accounts/master` - Create master organization (**semi-public bootstrap**; returns `api_key` + 500 credits) - `POST /users` - Create platform user (`provider` + `provider_subject`; optional before master create) - `POST /accounts/sub` - Create sub-organization - `GET /organizations` - List user's organizations - `GET /organizations/:id` - Get organization details - `PUT /organizations/:id` - Update organization settings - `GET /organizations/:id/billing` - Get billing info - `GET /organizations/:id/billing-organization` - Get billing parent - `GET /organizations/:id/consolidated-reporting` - Get consolidated reporting orgs - `GET /organizations/can-share-data/:org1/:org2` - Check data sharing ### Accounts (Chart of Accounts) - `POST /organizations/:org_id/accounts` - Create account - `GET /organizations/:org_id/accounts` - List accounts - `GET /organizations/:org_id/accounts/:id` - Get account details - `PUT /organizations/:org_id/accounts/:id` - Update account - `DELETE /organizations/:org_id/accounts/:id` - Delete account (if no transactions) - `GET /organizations/:org_id/accounts/:id/balance` - Get account balance - `GET /organizations/:org_id/accounts/:id/transactions` - Get account transaction history **Account Types**: `asset`, `liability`, `equity`, `revenue`, `expense` ### Transactions & Journal Entries - `POST /organizations/:org_id/transactions` - Create transaction with journal entries - `GET /organizations/:org_id/transactions` - List transactions - `GET /organizations/:org_id/transactions/:id` - Get transaction details - `PUT /organizations/:org_id/transactions/:id` - Update pending transaction - `DELETE /organizations/:org_id/transactions/:id` - Delete pending transaction - `POST /organizations/:org_id/transactions/:id/post` - Post transaction to ledger - `POST /organizations/:org_id/transactions/:id/reverse` - Reverse posted transaction ### Financial Reports - `GET /organizations/:org_id/reports/balance-sheet` - Balance sheet report - `GET /organizations/:org_id/reports/income-statement` - Income statement (P&L) - `GET /organizations/:org_id/reports/trial-balance` - Trial balance ### Contacts (Customers & Vendors) - `POST /organizations/:org_id/contacts` - Create contact - `GET /organizations/:org_id/contacts` - List contacts - `GET /organizations/:org_id/contacts/:id` - Get contact details - `PUT /organizations/:org_id/contacts/:id` - Update contact - `DELETE /organizations/:org_id/contacts/:id` - Delete contact ### Invoices - `POST /organizations/:org_id/invoices` - Create invoice - `GET /organizations/:org_id/invoices` - List invoices - `GET /organizations/:org_id/invoices/:id` - Get invoice details - `PUT /organizations/:org_id/invoices/:id` - Update invoice - `DELETE /organizations/:org_id/invoices/:id` - Delete draft invoice - `POST /organizations/:org_id/invoices/:id/send` - Send invoice to customer - `GET /organizations/:org_id/invoices/:id/pdf` - Generate invoice PDF - `POST /organizations/:org_id/invoices/:id/payments` - Record invoice payment - `GET /organizations/:org_id/invoices/:id/history` - Get invoice status history ### Bills - `POST /organizations/:org_id/bills` - Create bill - `GET /organizations/:org_id/bills` - List bills - `GET /organizations/:org_id/bills/:id` - Get bill details - `PUT /organizations/:org_id/bills/:id` - Update bill - `DELETE /organizations/:org_id/bills/:id` - Delete draft bill - `POST /organizations/:org_id/bills/:id/receive` - Mark bill as received - `POST /organizations/:org_id/bills/:id/payments` - Record bill payment - `GET /organizations/:org_id/bills/:id/history` - Get bill status history ### Transfers - `POST /organizations/:org_id/transfers` - Create account transfer - `GET /organizations/:org_id/transfers` - List transfers - `GET /organizations/:org_id/transfers/:id` - Get transfer details - `PUT /organizations/:org_id/transfers/:id` - Update transfer - `DELETE /organizations/:org_id/transfers/:id` - Delete transfer ### Recurring Transactions - `POST /organizations/:org_id/recurring` - Create recurring schedule - `GET /organizations/:org_id/recurring` - List recurring schedules - `GET /organizations/:org_id/recurring/:id` - Get schedule details - `PUT /organizations/:org_id/recurring/:id` - Update schedule - `DELETE /organizations/:org_id/recurring/:id` - Delete schedule - `POST /organizations/:org_id/recurring/:id/pause` - Pause schedule - `POST /organizations/:org_id/recurring/:id/resume` - Resume schedule ### Reconciliations - `POST /organizations/:org_id/reconciliations` - Start reconciliation - `GET /organizations/:org_id/reconciliations` - List reconciliations - `GET /organizations/:org_id/reconciliations/:id` - Get reconciliation details - `PUT /organizations/:org_id/reconciliations/:id` - Update reconciliation - `DELETE /organizations/:org_id/reconciliations/:id` - Delete reconciliation - `POST /organizations/:org_id/reconciliations/:id/complete` - Complete reconciliation ### API Keys - `POST /organizations/:org_id/api-keys` - Create API key - `GET /organizations/:org_id/api-keys` - List API keys - `GET /organizations/:org_id/api-keys/:id` - Get API key details - `PUT /organizations/:org_id/api-keys/:id` - Update API key - `POST /organizations/:org_id/api-keys/:id/rotate` - Rotate API key ### Credits - `GET /organizations/:org_id/credits/balance` - Get credit balance - `POST /organizations/:org_id/credits/purchase` - Purchase credits - `GET /credits/packages` - List credit packages ### Currencies & Exchange Rates - `GET /currencies` - List currencies - `POST /currencies` - Create currency - `GET /currencies/:id` - Get currency details - `PUT /currencies/:id` - Update currency - `GET /exchange-rates` - List exchange rates - `POST /exchange-rates` - Create exchange rate - `GET /exchange-rates/:id` - Get exchange rate - `PUT /exchange-rates/:id` - Update exchange rate ### Events - `GET /events/:entity_type/:entity_id` - Get entity audit events - `GET /organizations/:org_id/events` - Get organization events ## ID Prefixes All resource IDs use prefixes for easy identification: - `org_` - Organization - `act_` - Account - `txn_` - Transaction - `jnl_` - Journal Entry - `con_` - Contact - `inv_` - Invoice - `bil_` - Bill ## Data Models ### Account Object ```json { "id": "act_xxxxxxxxxxxxxxxx", "object": "account", "organization_id": "org_xxxxxxxxxxxxxxxx", "name": "Cash", "code": "1000", "type": "asset", "subtype": "current_asset", "currency": "USD", "description": "Primary operating cash account", "is_active": true, "parent_id": null, "balance": { "debit": 150000.00, "credit": 50000.00, "net": 100000.00 }, "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-20T14:22:00Z" } ``` ### Transaction Object ```json { "id": "txn_xxxxxxxxxxxxxxxx", "object": "transaction", "organization_id": "org_xxxxxxxxxxxxxxxx", "description": "Service revenue received", "date": "2024-01-15", "reference": "INV-001", "status": "posted", "entries": [ { "id": "jnl_xxxxxxxxxxxxxxxx", "account_id": "act_cash", "amount": 1000.00, "type": "debit", "description": "Cash received" }, { "id": "jnl_yyyyyyyyyyyyyyyy", "account_id": "act_revenue", "amount": 1000.00, "type": "credit", "description": "Service revenue" } ], "created_at": "2024-01-15T10:30:00Z" } ``` ## Credit-Based Billing 1 credit = $0.01 USD. Reads and reports are free. Writes cost at most 1 credit. | Operation Type | Credits | Examples | |----------------|---------|----------| | Read operations (GET) | 0 | List accounts, get transaction details, reports | | Write operations (POST/PUT/PATCH/DELETE) | 1 | Create account, post transaction, upload file | | MCP draft staging | 0 | create_draft, validate_draft (charged on approve) | **Credit Packages** (prepaid, not monthly subscriptions): - Solo Dev: $10 (1,000 credits) - Builder: $50 (5,000 credits) - Scale: $250 (25,000 credits) - Custom: $0.01 per credit ## Double-Entry Accounting Principles Crane Ledger enforces proper double-entry bookkeeping where every transaction must balance (total debits = total credits). ### Basic Transaction Example ```json { "description": "Service revenue received", "date": "2024-01-15", "entries": [ { "account_id": "act_xxxxxxxxxxxxxxxx", "amount": 1000.00, "type": "debit", "description": "Cash received from client" }, { "account_id": "act_yyyyyyyyyyyyyyyy", "amount": 1000.00, "type": "credit", "description": "Service revenue earned" } ] } ``` ### Complex Transaction Example (Expense Reimbursement) ```json { "description": "Employee expense reimbursement", "date": "2024-01-20", "entries": [ { "account_id": "act_cash", "amount": 500.00, "type": "debit" }, { "account_id": "act_employee_advance", "amount": 300.00, "type": "credit" }, { "account_id": "act_office_expenses", "amount": 200.00, "type": "credit" } ] } ``` ## Common Accounting Workflows ### Recording Customer Invoice 1. Create invoice → Debit Accounts Receivable, Credit Revenue 2. Receive payment → Debit Cash/Bank, Credit Accounts Receivable ### Processing Vendor Bill 1. Receive bill → Debit Expense, Credit Accounts Payable 2. Make payment → Debit Accounts Payable, Credit Cash/Bank ### Payroll Processing 1. Calculate payroll → Debit Salary Expense, Credit Cash (or various liability accounts) 2. Record tax withholdings → Debit various tax expense accounts, Credit tax liability accounts ## MCP (Model Context Protocol) Crane Ledger provides AI-native integration through the Model Context Protocol. ### Remote HTTP Endpoint (Streamable HTTP) | Setting | Value | |---------|-------| | URL | `https://api.craneledger.ai/mcp` | | Method | `POST` | | Transport | Streamable HTTP (JSON-RPC over single POST endpoint) | | Auth | OAuth 2.1 Bearer token **or** static `ha_live_...` / `ha_test_...` key | | OAuth discovery | `GET /.well-known/oauth-protected-resource` → `401` + `WWW-Authenticate` on unauthed requests | | Auth server | `https://auth.craneledger.ai` | | Scopes | `ledger:read`, `ledger:write`, `ledger:admin` | | Headers | `Content-Type: application/json`, `Accept: application/json, text/event-stream` | | Org scope | Derived from API key (no organization_id param required) | **Initialize example:** ```bash curl -s -X POST https://api.craneledger.ai/mcp \ -H "Authorization: Bearer ha_live_your_key" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"probe","version":"1.0"}}}' ``` **Claude CLI install:** ```bash claude mcp add --transport http crane-ledger https://api.craneledger.ai/mcp \ --header "Authorization: Bearer ha_live_your_key" ``` **JSON-RPC methods:** `initialize`, `notifications/initialized`, `tools/list`, `tools/call`, `prompts/list`, `prompts/get`, `resources/list`, `resources/read` **Docs:** https://craneledger.ai/docs/getting-started/mcp | https://craneledger.ai/docs/api-reference/mcp ### Available Tools (90 total) **Account Management (7)**: - `create_account`, `list_accounts`, `get_account`, `update_account`, `delete_account`, `get_account_balance`, `get_account_transactions` **Transaction Processing (7)**: - `create_transaction`, `list_transactions`, `get_transaction`, `update_transaction`, `delete_transaction`, `post_transaction`, `reverse_transaction` **Invoice Management (9)**: - `create_invoice`, `list_invoices`, `get_invoice`, `update_invoice`, `delete_invoice`, `send_invoice`, `generate_invoice_pdf`, `record_invoice_payment`, `get_invoice_history` **Bill Management (7)**: - `create_bill`, `list_bills`, `get_bill`, `update_bill`, `delete_bill`, `receive_bill`, `get_bill_history` **Contact Management (3)**: `list_contacts`, `get_contact`, `create_contact` **Transfer Management (5)**: `list_transfers`, `get_transfer`, `create_transfer`, `update_transfer`, `delete_transfer` **Organization Management (9)**: - `create_master_account`, `create_sub_organization`, `get_user_organizations`, `get_organization`, `update_organization`, `get_organization_billing`, `get_billing_organization`, `get_consolidated_reporting_orgs`, `check_data_sharing` **Financial Reporting (3)**: `get_trial_balance`, `get_balance_sheet`, `get_income_statement` **Currency & Exchange (8)**: `list_currencies`, `get_currency`, `create_currency`, `update_currency`, `list_exchange_rates`, `get_exchange_rate`, `create_exchange_rate`, `update_exchange_rate` **Reconciliation (6)**: `list_reconciliations`, `create_reconciliation`, `get_reconciliation`, `update_reconciliation`, `complete_reconciliation`, `delete_reconciliation` **Recurring (7)**: `list_recurring_schedules`, `create_recurring_schedule`, `get_recurring_schedule`, `update_recurring_schedule`, `pause_recurring_schedule`, `resume_recurring_schedule`, `delete_recurring_schedule` **API Keys (5)**: `list_api_keys`, `create_api_key`, `get_api_key`, `update_api_key`, `rotate_api_key` **Credits (5)**: `get_credit_balance`, `purchase_credits`, `get_credit_packages`, `start_x402_credit_purchase`, `complete_x402_credit_purchase` **Draft / Approve (6)**: `create_draft`, `validate_draft`, `approve_draft`, `reject_draft`, `get_draft`, `list_drafts` — stage agent writes; approve charges once **System (3)**: `health_check`, `system_info`, `get_entity_events` ### Local stdio MCP Server Configuration (development) ```json { "mcpServers": { "crane-ledger": { "command": "/path/to/mcp-server", "env": { "API_BASE_URL": "https://api.craneledger.ai", "API_KEY": "ha_live_your_key_here", "ORGANIZATION_ID": "org_your_org_id" } } } } ``` ## GraphQL API GraphQL endpoint: `https://api.craneledger.ai/graphql` Playground: `https://api.craneledger.ai/graphql/playground` ### GraphQL Schema Types #### Core Types - `OrganizationNode` - Organization with settings, accounts, contacts, transactions - `AccountNode` - Chart of accounts entries with balances and transactions - `TransactionNode` - Journal entries with debits/credits - `ContactNode` - Customers, vendors, employees - `InvoiceNode` - Sales invoices with payments - `BillNode` - Purchase bills with payments - `CurrencyNode` - Currency information - `MoneyNode` - Monetary amounts with currency formatting #### Report Types - `TrialBalanceReport` - Account balances verification - `BalanceSheetReport` - Financial position statement - `IncomeStatementReport` - Profit & loss statement #### Enums - `AccountType` - ASSET, LIABILITY, EQUITY, REVENUE, EXPENSE - `AccountStatus` - ACTIVE, INACTIVE, SUSPENDED - `TransactionStatus` - PENDING, POSTED, FAILED, REVERSED - `EntryType` - DEBIT, CREDIT - `ContactType` - CUSTOMER, VENDOR, EMPLOYEE - `InvoiceStatus` - DRAFT, SENT, VIEWED, PAID, OVERDUE, CANCELLED - `BillStatus` - DRAFT, RECEIVED, PARTIAL, PAID, OVERDUE, CANCELLED ### Core Queries #### Organization Queries ```graphql # Get current organization (based on API key) query { organization { id name baseCurrency { code name symbol } creditsRemaining accounts { id code name accountType balance { formatted } } recentTransactions(limit: 5) { id description amount date } trialBalance { totalDebits totalCredits } } } # Get specific organization query GetOrganization($id: ID!) { organizationById(id: $id) { id name baseCurrency { code } } } ``` #### Account Queries ```graphql # Get account details and balance query GetAccount($id: ID!) { account(id: $id) { id code name accountType status balance { amount formatted currency { code } } transactions(limit: 10) { id description date amount status } } } ``` #### Transaction Queries ```graphql # Get transaction with journal entries query GetTransaction($id: ID!) { transaction(id: $id) { id description date status amount currency { code } entries { accountId entryType amount baseAmount description } } } ``` #### Contact Queries ```graphql # Get contact with relationships query GetContact($id: ID!) { contact(id: $id) { id name contactType email phone transactions(limit: 5) { id description amount } invoices { id invoiceNumber total status } bills { id billNumber total status } } } ``` #### Document Queries ```graphql # Get invoice with payments query GetInvoice($id: ID!) { invoice(id: $id) { id invoiceNumber status total currency { code } contactId invoiceDate dueDate items { description quantity unitPrice lineTotal } payments { amount paymentDate paymentMethod } pdfUrl } } # Get bill with payments query GetBill($id: ID!) { bill(id: $id) { id billNumber status total currency { code } contactId billDate dueDate items { description quantity unitPrice lineTotal } payments { amount paymentDate paymentMethod } pdfUrl } } ``` #### Report Queries ```graphql # Trial balance - verifies accounting equation query { organization { trialBalance { generatedAt accounts { accountCode accountName accountType debitBalance creditBalance netBalance } totalDebits totalCredits } } } # Balance sheet - financial position query { organization { balanceSheet { generatedAt asOfDate assets { accountName balance } liabilities { accountName balance } equity { accountName balance } totalAssets totalLiabilities totalEquity } } } # Income statement - profit & loss query { organization { incomeStatement { generatedAt periodStart periodEnd revenue { accountName amount } expenses { accountName amount } totalRevenue totalExpenses netIncome } } } ``` ### Mutations #### Account Mutations ```graphql # Create account mutation CreateAccount($code: String!, $name: String!, $type: AccountType!) { createAccount(code: $code, name: $name, accountType: $type) { id code name accountType status createdAt } } # Update account mutation UpdateAccount($id: ID!, $name: String) { updateAccount(id: $id, name: $name) { id name updatedAt } } # Delete account (no transactions required) mutation DeleteAccount($id: ID!) { deleteAccount(id: $id) } ``` #### Contact Mutations ```graphql # Create contact mutation CreateContact($name: String!, $type: ContactType!, $email: String) { createContact(name: $name, contactType: $type, email: $email) { id name contactType email createdAt } } # Update contact mutation UpdateContact($id: ID!, $email: String) { updateContact(id: $id, email: $email) { id name email updatedAt } } # Delete contact mutation DeleteContact($id: ID!) { deleteContact(id: $id) } ``` #### Transaction Mutations ```graphql # Create transaction with journal entries mutation CreateTransaction( $description: String! $date: DateTime! $entries: [LedgerEntryInput!]! ) { createTransaction( description: $description date: $date entries: $entries ) { id description status amount entries { accountId entryType amount description } } } # LedgerEntryInput structure { accountId: "ACT_123..." entryType: "DEBIT" # or "CREDIT" amount: 100.00 description: "Optional entry description" } ``` #### Document Mutations ```graphql # Create invoice mutation CreateInvoice( $contactId: ID! $invoiceDate: DateTime! $dueDate: DateTime! $items: [InvoiceItemInput!]! ) { createInvoice( contactId: $contactId invoiceDate: $invoiceDate dueDate: $dueDate items: $items ) { id invoiceNumber total status items { description quantity unitPrice lineTotal } } } # InvoiceItemInput structure { description: "Service description" quantity: 10.0 unitPrice: 50.00 } # Record invoice payment mutation RecordInvoicePayment( $invoiceId: ID! $amount: Decimal! $paymentDate: DateTime! $paymentMethod: String! ) { recordInvoicePayment( invoiceId: $invoiceId amount: $amount paymentDate: $paymentDate paymentMethod: $paymentMethod ) { id amount paymentDate paymentMethod } } # Create bill mutation CreateBill( $contactId: ID! $billDate: DateTime! $dueDate: DateTime! $items: [BillItemInput!]! ) { createBill( contactId: $contactId billDate: $billDate dueDate: $dueDate items: $items ) { id billNumber total status items { description quantity unitPrice lineTotal } } } # Record bill payment mutation RecordBillPayment( $billId: ID! $amount: Decimal! $paymentDate: DateTime! $paymentMethod: String! ) { recordBillPayment( billId: $billId amount: $amount paymentDate: $paymentDate paymentMethod: $paymentMethod ) { id amount paymentDate paymentMethod } } ``` ### GraphQL Error Codes GraphQL errors include structured error codes in the `extensions` field: - `UNAUTHENTICATED` - Missing or invalid API key - `FORBIDDEN` - Access denied to resource - `NOT_FOUND` - Resource not found - `VALIDATION_ERROR` - Input validation failed - `CONFLICT` - Resource conflict (duplicate, constraint violation) - `RATE_LIMIT_EXCEEDED` - Too many requests - `INTERNAL_ERROR` - Server error ### Authentication GraphQL uses the same Bearer token authentication as REST API: ```graphql # All requests require Authorization header Authorization: Bearer ha_live_your_api_key_here ``` ### Best Practices 1. **Request Only Needed Fields** - GraphQL allows precise field selection 2. **Use Fragments** - Reusable field sets for common queries 3. **Pagination** - Use `limit` parameters for large result sets 4. **Error Handling** - Always check for `errors` in response 5. **Batching** - Combine related operations in single requests ### Credit Management ```graphql # Get credit balance query { creditBalance { creditsRemaining creditsTotal autoRechargeEnabled } } # Get available credit packages query { creditPackages { packageType credits name priceUsd } } # Purchase credits mutation PurchaseCredits($creditAmount: Int!, $successUrl: String, $cancelUrl: String) { purchaseCredits( creditAmount: $creditAmount successUrl: $successUrl cancelUrl: $cancelUrl ) { checkoutUrl creditsToAdd priceCents expiresAt } } ``` ## HTTP Status Codes & Error Handling ### Success Codes - `200` - OK (successful GET/PUT/PATCH) - `201` - Created (successful POST) - `204` - No Content (successful DELETE) ### Client Error Codes - `400` - Bad Request (invalid parameters, malformed JSON) - `401` - Unauthorized (missing/invalid API key) - `403` - Forbidden (insufficient permissions, org access denied) - `404` - Not Found (resource doesn't exist) - `409` - Conflict (duplicate resource, constraint violation) - `422` - Unprocessable Entity (validation error, unbalanced transaction) - `429` - Too Many Requests (rate limit exceeded) ### Server Error Codes - `500` - Internal Server Error (unexpected error) - `502` - Bad Gateway (upstream service error) - `503` - Service Unavailable (maintenance mode) ### Common Error Response Format ```json { "error": { "type": "validation_error", "message": "Transaction entries must balance (debits = credits)", "details": { "total_debits": 1500.00, "total_credits": 1000.00, "difference": 500.00 }, "suggestion": "Add missing credit entry or adjust amounts to balance" } } ``` ## Rate Limits & Best Practices - **API Rate Limit**: 1000 requests per minute per organization - **Credit Limits**: Vary by plan (see billing section) - **Batch Operations**: Use for bulk imports/updates - **Webhooks**: Subscribe to real-time events instead of polling - **Caching**: Cache account lists and static data - **Pagination**: Use cursor-based pagination for large datasets ## Documentation Full documentation: https://craneledger.ai/docs API Reference: https://craneledger.ai/docs/api-reference/accounts ## Support - Email: support@craneledger.ai - Sales: sales@craneledger.ai © 2026 Crane X1 LLC d/b/a Crane Ledger. All Rights Reserved.