{
  "schema": "aaes/capability-pack/1",
  "provider": "navan",
  "version": "1.0.0",
  "description": "Read Navan expense transactions and receipt links, and batch-update accounting attributes on existing transactions. Updates do not change approval status. Covers the Expense API, not travel booking or payments.",
  "notes": "Use Navan API credentials whose scopes cover only what these capabilities need; the pack does not create them. This pack registers only the Navan Expense API surface documented in the official developer portal: the retrieval endpoints under https://api.navan.com/v1/expense and the batch PATCH update on /v1/expense/transactions.\n\nAll reads are collection reads only — the single-transaction read (GET /v1/expense/transactions/{id}) and the single-transaction receipt endpoints exist in the API and are deliberately not registered, and every list call must carry a date filter (Navan rejects requests without one; windows are capped at 93 days).\n\nThe PATCH capability is registered as update at the minimum R2 tier: it changes accounting attributes on existing transactions (ERP sync status, GL codes, HR fields, custom field values) — it is request-accepted with per-transaction status in the response, and the reference's documented updatable field list for this PATCH (transaction id, ERP sync status — updates to SYNCED only — plus external ERP reference fields, GL code number and name, the HR fields department/region/subsidiary/cost_center, and custom field values) contains no approval-status field, so the update cannot change approval status and is not an approval action.\n\nDocumented exclusions, framed as what this pack does not register: travel bookings — the official token example shows a bookings:read scope and Navan operates a Booking Data API, but its endpoint reference is not part of the official documentation retrieved for this review, so this pack registers no bookings endpoint; users — no users endpoint appears in the retrieved official Expense API documentation; expense approval — the reviewed documentation describes no approve endpoint, and the PATCH update cannot set approval_status; receipts download redirects (the redirect target is a presigned URL on another host and AAES does not follow redirects); the hosted Navan MCP server (mcp.navan.com), a separate user-context surface; and every write other than the registered PATCH.\n\nEU deployments: Navan documents that EU companies must send the X-ta-region=EU header on every request and use the EU token endpoint — the deployment must wire that header before enabling against an EU tenant.\n\nTransaction data may take up to 4 hours to appear in GET results after an update. AAES has not been certified by Navan; the endpoints here are configuration to review and test; the vendor has not endorsed it.\n\nSource annotation for https://docs.navan.com/api/ (retrieved 2026-09-21): — Authentication: OAuth 2.0 client-credentials grant, 12-hour default token validity, Expense: Write scope requirement for PATCH, explicit-scope override warning\nSource annotation for https://docs.navan.com/api/ (retrieved 2026-09-21): — section 1 'Retrieve Navan card transactions' (GET /v1/expense/card-transactions): required date filter, card-specific fields\nSource annotation for https://docs.navan.com/api/ (retrieved 2026-09-21): — section 3 'Retrieve manual transactions' (GET /v1/expense/manual-transactions)\nSource annotation for https://docs.navan.com/api/ (retrieved 2026-09-21): — section 9 'Generic API — retrieve all transaction types' (GET /v1/expense/transactions): required type array and date filter, _type discriminator\nSource annotation for https://docs.navan.com/api/ (retrieved 2026-09-21): — section 11c 'Get receipt links by date filter' (GET /v1/expense/transactions/receipts): required type[] and date parameter, presigned URLs not to be cached\nSource annotation for https://docs.navan.com/api/ (retrieved 2026-09-21): — section 'Update transactions endpoint (batch update with PATCH)' (PATCH /v1/expense/transactions): updatable field groups contain no approval-status field, per-transaction results[].status, 4-hour GET visibility delay",
  "credential": {
    "secret_ref_id": "secret-ref-navan-expense-token",
    "custody": "customer_vault",
    "inject": "header",
    "inject_name": "Authorization",
    "note": "An OAuth 2.0 access token for the Navan Expense API, held in the client's own secret manager. The stored material must be the complete Authorization header value (scheme included): 'Bearer', one separating space, then the access token — 'Bearer <token>'.\n\nAn external token process mints it with the client credentials grant: an admin creates API credentials (client_id and client_secret) in the Navan platform, and the process POSTs grant_type=client_credentials with the client_id and client_secret to https://app.navan.com/ta-auth/oauth/token (https://app-fra.navan.com/ta-auth/oauth/token for EU companies) and stores the returned access token; the client secret is itself secret material and stays with that external process.\n\nNavan documents tokens as valid for 12 hours by default, so the external process must refresh on expiry — the executor must not attempt renewal itself; the API credentials can be rescoped or revoked in the Navan platform at any time, and an expired or revoked value fails closed. Do not pass an explicit scope parameter at token time: Navan documents that an explicit scope overrides and limits the token's permissions.\n\nLeast privilege: credentials are read-only by default — only the PATCH capability needs the Expense: Write scope, so a read-only deployment should not grant it, and a deployment that enables the update capability must accept exactly that one write scope. EU deployments must also send the X-ta-region=EU header on every request; that wiring is a pre-enablement review item.\n\nExecutor hygiene: the token must live only in executor memory for the lifetime of a call, must never be written to logs, traces or diagnostics, and must never appear in crash reports; the executor's memory, log and crash handling are otherwise the deployment's review."
  },
  "capabilities": [
    {
      "capability_id": "navan.expense.card-transactions.read",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "financial",
      "egress_allowlist": [
        "api.navan.com"
      ],
      "endpoint": "https://api.navan.com/v1/expense/card-transactions",
      "method": "GET",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-navan-expense-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "read"
      ],
      "resource_id": "navan-expense",
      "description": "Query the Navan card transactions collection (virtual and physical cards): amounts, merchants, cardholders, GL coding, policy flags and approval status, classified as financial data. A date filter is required on every call. The registered path covers the collection read only — the generic multi-type read and single-transaction reads are registered separately or not at all.",
      "requires_review": true
    },
    {
      "capability_id": "navan.expense.manual-transactions.read",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "financial",
      "egress_allowlist": [
        "api.navan.com"
      ],
      "endpoint": "https://api.navan.com/v1/expense/manual-transactions",
      "method": "GET",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-navan-expense-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "read"
      ],
      "resource_id": "navan-expense",
      "description": "Query the manual transactions collection: employee manual expense submissions, including reimbursements and payroll expenses, with amounts, submitters, GL coding and approval status, classified as financial data. A date filter is required on every call. The registered path covers the collection read only.",
      "requires_review": true
    },
    {
      "capability_id": "navan.expense.transactions.read",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "financial",
      "egress_allowlist": [
        "api.navan.com"
      ],
      "endpoint": "https://api.navan.com/v1/expense/transactions",
      "method": "GET",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-navan-expense-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "read"
      ],
      "resource_id": "navan-expense",
      "description": "Query the generic transactions collection across the documented types (card, Connect card, manual, repayments, fees, adjustments, daily rebates, disputes) selected with the type parameter, classified as financial data. A date filter is required on every call. The registered path covers the collection read only — single-transaction reads (GET /v1/expense/transactions/{id}) are not registered by this pack.",
      "requires_review": true
    },
    {
      "capability_id": "navan.expense.receipts.read",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "financial",
      "egress_allowlist": [
        "api.navan.com"
      ],
      "endpoint": "https://api.navan.com/v1/expense/transactions/receipts",
      "method": "GET",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-navan-expense-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "read"
      ],
      "resource_id": "navan-expense",
      "description": "Query receipt links for transactions matching a transaction-type array (type[]) and a date filter — both required per the reference: the response carries transaction ids and presigned receipt and e-receipt URLs (presigned; the reference states they should not be cached), classified as financial data. The registered path covers the collection read only — the download endpoints redirect (302) to presigned URLs on another host, AAES does not follow redirects, and the presigned URLs themselves are not registered destinations.",
      "requires_review": true
    },
    {
      "capability_id": "navan.expense.transactions.update",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R2",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "financial",
      "egress_allowlist": [
        "api.navan.com"
      ],
      "endpoint": "https://api.navan.com/v1/expense/transactions",
      "method": "PATCH",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-navan-expense-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "update"
      ],
      "resource_id": "navan-expense",
      "description": "Batch-update accounting attributes on existing transactions (up to 100 per call): ERP sync status (updates to SYNCED only), external transaction references, GL code number and name (must be set together), HR fields (department, region, subsidiary, cost center) and custom field values.\n\nResult: a 200 response is request-accepted — per-transaction outcomes are reported in results[].status — and Navan documents that updated data may take up to 4 hours to appear in GET results. Registered as update at the minimum R2 tier; the reference's documented updatable field list for this PATCH contains no approval-status field, so the call cannot change approval status and is not an approval action.\n\nRequires the Expense: Write scope on the credential; Navan documents that read-only credentials receive 403 from this endpoint.",
      "requires_review": true
    }
  ],
  "resources": [
    {
      "resource_id": "navan-expense",
      "kind": "api",
      "locator": "https://api.navan.com/v1/expense",
      "data_class": "financial",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN"
    }
  ],
  "review": {
    "state": "library",
    "date": "2026-10-22",
    "sources": [
      "https://docs.navan.com/api/ (retrieved 2026-09-21)",
      "https://docs.navan.com/llms.txt (retrieved 2026-09-21)",
      "https://docs.navan.com/mcp/index.md (retrieved 2026-09-21)"
    ],
    "reviewer_id": "owner-delegated"
  }
}
