MCP Tools Reference

Overview

The Branch MCP server gives AI agents read-only access to the Branch API documentation. This page lists each tool it provides, along with parameter specifications, code samples, and example responses. To connect a client such as Claude, Cursor, or VS Code, see MCP.

Server details

  • Server URL: https://docs.branchapp.com/mcp
  • Transport: Streamable HTTP · Authentication: none
  • Protocol: 2025-06-18 · Tools: 8, all read-only

Install

Run in a terminal

claude mcp add --transport http branch https://docs.branchapp.com/mcp

For step-by-step setup and Claude Enterprise options, see MCP.

Tools

Agents typically chain them: search → fetch to read a guide, and search-endpoints → get-endpoint to look up an API operation.

Quickstart

Branch Overview

branch-overviewread-only

Call this when the user is new to Branch or is asking what Branch is, what it does, how its core objects relate (organizations, workers, wallets, payment profiles, disbursements), or where to begin an integration. Returns a one-page orientation: the object model, the worker lifecycle from onboarding through payment, the two integration approaches, and the sandbox and production environments. For specific procedures or API details, use search, fetch, and get-endpoint instead — this tool is orientation only.

Read-only · No side effects · Branch docs only

Parameters

This tool takes no arguments.

Returns: A one-page orientation to Branch as plain text: the object model, the worker lifecycle, the two integration approaches, and the sandbox and production environments.

Example prompt: "What is Branch, and where should I start with an integration?"

Request

curl -X POST https://docs.branchapp.com/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"branch-overview","arguments":{}}}'
# pip install "mcp>=2"
import asyncio
from mcp import Client

async def main():
    async with Client("https://docs.branchapp.com/mcp") as client:
        result = await client.call_tool("branch-overview", {})
        print(result.content[0].text)

asyncio.run(main())
// npm install @modelcontextprotocol/sdk
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const client = new Client({ name: "my-app", version: "1.0.0" });
await client.connect(new StreamableHTTPClientTransport(new URL("https://docs.branchapp.com/mcp")));

const result = await client.callTool({ name: "branch-overview", arguments: {} });
console.log(result.content[0].text);
await client.close();

Response

Branch provides fast, flexible payments to a workforce. An
Organization (a Branch customer) sends payments to its Workers
through the Branch API, without pre-funding and without the timing
of traditional ACH.

CORE OBJECTS

Organization
  The Branch customer. Identified by a numeric org ID in API paths
  (for example 100000). Onboarding URLs use a separate Organization
  UUID instead.

Worker (also called Employee)
  A person paid by the Organization. The Organization assigns the ID
  itself and reuses it on every later call. IMPORTANT: "Worker" and
  "Employee" are the same entity. V1 endpoints say Employee, V2 say
  Worker, and an employee_id from V1 works as a worker_id in V2 and
  vice versa. Do not create a second record.
  See branch-developer/worker-and-employee-compatibility

Payment method
  How a Worker receives money. Two kinds:
  - Branch Wallet: a Branch-held account with its own account and
    routing number. The Worker claims it and can use the Branch app.
  - Branch Direct: the Worker links a personal debit card they
    already have.

Payment Profile
  The Worker's active payment method. A Worker is only payable once a
  payment profile is active. Subscribing to PAYMENT_PROFILE_ACTIVATED
  is required to confirm payment eligibility.

Disbursement
  Any payment to a Worker: a paycheck, tips, mileage, or an automatic
  payout after a shift. All are disbursements.

Invoice
  Branch fronts disbursements, then invoices the Organization to
  repay them by ACH. No pre-funding is required.
  See branch-developer/disbursement-invoices

LIFECYCLE

1. The Organization tells Branch about the Worker.
   Create Employee (V1) or Create Wallet (V2).
2. The Worker onboards: chooses a payment method and passes KYC.
   Branch emits webhooks as the wallet moves through its statuses.
3. The Worker becomes payable. Wallet status UNCLAIMED means funds
   can be sent even before the Worker has signed up. PENDING means
   not yet payable.
4. The Organization creates disbursements.
5. Branch invoices the Organization by ACH.

There is no single "is payable" field. Payability is assembled from
wallet status plus payment profile state.

TWO INTEGRATION APPROACHES

Standard Web Portal (recommended)
  Branch hosts the onboarding, payment history, and payment profile
  screens. The Organization embeds a widget or links out. Lightweight
  to build and maintain.

Embedded API
  The Organization builds its own screens against Branch APIs. More
  control over the experience, more to build and maintain.
  See branch-developer/embedded-api

ENVIRONMENTS

Sandbox   https://sandbox.branchapp.com
  Payouts are simulated, KYC results are preset, no money moves.
Production  https://api.branchapp.com
  Real PII required. One Branch account per person.

API keys are separate per environment. Branch certifies an
Organization in each environment before it moves to the next.
See branch-developer/environments

VERSIONS

The version is in the URL path (/v1/, /v2/). V2 is current. Breaking
changes only arrive in a new version.
See branch-developer/api-versions

BEYOND DISBURSEMENTS

Earned Wage Access (advances against earned wages), cards, and
reporting are also part of the platform.
See branch-developer/earned-wage-access

WHERE TO GO NEXT

  branch-developer/developer-overview       full integration overview
  branch-developer/employee-create          onboard a worker (V1)
  branch-developer/wallet-create            onboard a worker (V2)
  branch-developer/disbursement-create      send a payment
  branch-developer/disbursement-error-handling
                                            status and reason codes
  branch-developer/webhook-implementation   receive events
  branch-developer/manage-secret-keys       API keys
  branch-developer/rate-limits              rate limits

Use list-webhook-events for the full webhook catalog, and
list-endpoints or search-endpoints for the API surface.

API discovery

List API Endpoints

list-endpointsread-only

Lists all API paths and their HTTP methods with summaries, organized by path. Results can be passed directly into 'get-endpoint'.

Read-only · No side effects · Branch docs only

Parameters

This tool takes no arguments.

Returns: Every API path with its HTTP methods and a one-line summary of each, as JSON keyed by path.

Example prompt: "List all of the Branch API endpoints."

Request

curl -X POST https://docs.branchapp.com/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list-endpoints","arguments":{}}}'
# pip install "mcp>=2"
import asyncio
from mcp import Client

async def main():
    async with Client("https://docs.branchapp.com/mcp") as client:
        result = await client.call_tool("list-endpoints", {})
        print(result.content[0].text)

asyncio.run(main())
// npm install @modelcontextprotocol/sdk
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const client = new Client({ name: "my-app", version: "1.0.0" });
await client.connect(new StreamableHTTPClientTransport(new URL("https://docs.branchapp.com/mcp")));

const result = await client.callTool({ name: "list-endpoints", arguments: {} });
console.log(result.content[0].text);
await client.close();

Response

{
  "/v2/organizations/{orgId}/workers/{workerId}/advances/eligibility": {
    "get": "Get Worker Advance Eligibility",
    "put": "Update Worker Advance Eligibility"
  },
  "/v1/organizations/{orgId}/advances": {
    "get": "Search Advances"
  },
  "/v1/organizations/{orgId}/employees/{employeeId}/card": {
    "get": "Get Activated User Card"
  },
  "/v2/organizations/{orgId}/payouts/card/{payoutId}": {
    "get": "Get External Card Payout"
  },
  "/v2/organizations/{orgId}/workers/{workerId}/disbursements": {
    "get": "Search Worker Disbursements",
    "post": "Create Disbursement",
    "delete": "Cancel Disbursement"
  },
  "/v2/organizations/{orgId}/disbursements": {
    "get": "Search Disbursements"
  },
  "/v2/organizations/{orgId}/disbursements/reversals": {
    "get": "Search Disbursement Reversals",
    "post": "Create Disbursement Reversal"
  },
  "/v2/organizations/{orgId}/disbursements/fees/calculate": {
    "post": "Calculate Disbursement Fee"
  },
  "/v2/organizations/{orgId}/disbursements/fees": {
    "get": "Get Disbursement Fees"
  },
  "/v1/organizations/{orgId}/employees/{employeeId}/disbursements": {
    "get": "Search Employee Disbursements",
    "post": "Create Disbursement"
  },
  "/v1/organizations/{orgId}/invoices/{invoiceId}/disbursements": {
    "get": "Search Invoice Disbursements"
  },
  "/v1/organizations/{orgId}/disbursements": {
    "get": "Search Disbursements"
  },
  "/v1/organizations/{orgId}/employees/{employeeId}": {
    "get": "Get Employee",
    "put": "Update Employee",
    "post": "Create Employee",
    "delete": "Delete Employee"
  },
  "/v1/organizations/{orgId}/employees": {
    "get": "Search Employees"
  },
  "/v1/organizations/{orgId}/employees/{employeeId}/address": {
    "get": "Get Employee Address"
  },
  "/v1/organizations/{orgId}/employees/{employeeId}/period-earnings": {
    "put": "Update Employee Earning"
  },
  "/v2/organizations/{orgId}/workers/{workerId}/ewa/available-balance": {
    "get": "Get EWA Available Balance"
  },
  "/v2/organizations/{orgId}/workers/{workerId}/ewa/account": {
    "get": "Get EWA Account"
  },
  "/v2/organizations/{orgId}/workers/{workerId}/external-cards": {
    "get": "Search External Cards",
    "post": "Add External Card"
  },
  "/v2/organizations/{orgId}/workers/{workerId}/external-cards/{externalCardId}": {
    "get": "Get External Card",
    "delete": "Delete External Card"
  },
  "/v1/organizations": {
    "get": "Search Organizations",
    "post": "Create Organization"
  },
  "/v1/organizations/{orgId}": {
    "get": "Get Organization",
    "delete": "Deactivate Organization",
    "patch": "Update Organization"
  },
  "/v2/organizations/{orgId}/workers/{workerId}/payment-profile": {
    "get": "Get Payment Profile",
    "put": "Update Payment Profile"
  },
  "/v1/organizations/{orgId}/payroll-calendar": {
    "get": "Get Payroll Calendar",
    "post": "Create Payroll Calendar"
  },
  "/v1/organizations/{orgId}/payroll-calendar/periods/{payrollPeriodId}": {
    "get": "Get Payroll Period",
    "put": "Update Payroll Period"
  },
  "/v1/organizations/{orgId}/remittances/{remittanceId}/deductions": {
    "post": "Report Remittance Deduction"
  },
  "/v1/organizations/{orgId}/remittances/{remittanceId}": {
    "patch": "Complete Remittance Deduction"
  },
  "/v1/organizations/{orgId}/remittances": {
    "get": "Search Remittances"
  },
  "/v1/organizations/{orgId}/remittances/{remittanceId}/requested-deductions": {
    "get": "Search Remittance Requested Deductions"
  },
  "/v2/organizations/{orgId}/workers/{workerId}/rewards/lifetime_summary": {
    "get": "Get Worker Rewards Lifetime Summary"
  },
  "/v2/organizations/{orgId}/workers/{workerId}/shifts/{shiftId}": {
    "get": "Get Shift",
    "put": "Update Shift",
    "delete": "Delete Shift"
  },
  "/v2/organizations/{orgId}/workers/{workerId}/shifts": {
    "post": "Submit Shift"
  },
  "/v1/organizations/{orgId}/employees/{employeeId}/shifts/{shiftId}": {
    "get": "Get Shift",
    "put": "Update Shift",
    "delete": "Delete shift"
  },
…

Search API Endpoints

search-endpointsread-only

Performs a deep search through paths, operations, and parameters to discover relevant API endpoints. Use this tool to find specific API capabilities, required parameters, or data models based on search keywords. Results can be passed directly into 'get-endpoint'.

Read-only · No side effects · Branch docs only

Parameters

  • pattern string · required
    Search pattern (case-insensitive)

Returns: Matching endpoints (method, path, and summary), grouped by API. Pass any result to get-endpoint for full details.

Example prompt: "Which Branch endpoints deal with disbursements?"

Request

curl -X POST https://docs.branchapp.com/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"search-endpoints","arguments":{"pattern":"disbursement"}}}'
# pip install "mcp>=2"
import asyncio
from mcp import Client

async def main():
    async with Client("https://docs.branchapp.com/mcp") as client:
        result = await client.call_tool("search-endpoints", {"pattern": "disbursement"})
        print(result.content[0].text)

asyncio.run(main())
// npm install @modelcontextprotocol/sdk
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const client = new Client({ name: "my-app", version: "1.0.0" });
await client.connect(new StreamableHTTPClientTransport(new URL("https://docs.branchapp.com/mcp")));

const result = await client.callTool({ name: "search-endpoints", arguments: { pattern: "disbursement" } });
console.log(result.content[0].text);
await client.close();

Response

[
  {
    "title": "Branch API (reference)",
    "endpoints": [
      {
        "method": "GET",
        "path": "/v2/organizations/{orgId}/payouts/card/{payoutId}",
        "summary": "Get External Card Payout"
      },
      {
        "method": "GET",
        "path": "/v2/organizations/{orgId}/workers/{workerId}/disbursements",
        "summary": "Search Worker Disbursements"
      },
      {
        "method": "POST",
        "path": "/v2/organizations/{orgId}/workers/{workerId}/disbursements",
        "summary": "Create Disbursement"
      },
      "… 11 more"
    ]
  }
]

Get Endpoint Details

get-endpointread-only

Gets detailed information about a specific API endpoint, including security schemes and servers

Read-only · No side effects · Branch docs only

Parameters

  • path string · required
    The API endpoint path (e.g. /api/v1/users).
  • method string · required
    The HTTP method (e.g. GET, POST, PUT, DELETE).

Returns: The OpenAPI definition for that one operation: parameters, request body, response schemas, security scheme, and server URLs.

Example prompt: "Show me the request body for creating a disbursement."

Request

curl -X POST https://docs.branchapp.com/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get-endpoint","arguments":{"path":"/v2/organizations/{orgId}/workers/{workerId}/disbursements","method":"POST"}}}'
# pip install "mcp>=2"
import asyncio
from mcp import Client

async def main():
    async with Client("https://docs.branchapp.com/mcp") as client:
        result = await client.call_tool("get-endpoint", {"path": "/v2/organizations/{orgId}/workers/{workerId}/disbursements", "method": "POST"})
        print(result.content[0].text)

asyncio.run(main())
// npm install @modelcontextprotocol/sdk
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const client = new Client({ name: "my-app", version: "1.0.0" });
await client.connect(new StreamableHTTPClientTransport(new URL("https://docs.branchapp.com/mcp")));

const result = await client.callTool({ name: "get-endpoint", arguments: { path: "/v2/organizations/{orgId}/workers/{workerId}/disbursements", method: "POST" } });
console.log(result.content[0].text);
await client.close();

Response

{
  "openapi": "3.1.0",
  "servers": [
    {
      "url": "https://api.branchapp.com",
      "description": "Production URL"
    },
    {
      "url": "https://sandbox.branchapp.com",
      "description": "Sandbox URL"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "paths": {
    "/v2/organizations/{orgId}/workers/{workerId}/disbursements": {
      "post": {
        "tags": [
          "V2 Disbursements"
        ],
        "summary": "Create Disbursement",
        "description": "Creates a disbursement for a worker. A disbursement is an initiation of payment to a worker. In sandbox, providing a value from [this table](/docs/testing-disbursements#generated-response-values-for-mock_response) to `metadata.mock_response` will return a mock disbursement with a corresponding `reason_code`, `status`, and HTTP Response Code. ",
        "operationId": "create-disbursement-v2",
        "parameters": [
          {
            "name": "orgId",
            "in": "path",
            "description": "Organization ID",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 123456
          },
          {
            "name": "workerId",
            "in": "path",
            "description": "Worker ID",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": 123
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/V2DisbursementCreateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Returned if the disbursement already exists and an additional attempt to disburse funds was not made. This can occur if the disbursement was already complete or if the resulting status is in [ CANCELED | SKIPPED | REVERSED ]\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/V2DisbursementDto"
                },
                "examples": {
                  "Canceled": {
                    "value": {
                      "worker_id": "123456",
                      "amount": 100,
                      "external_id": "090eaa89-77f6-4f06-b352-a8e8a277f966",
                      "type": "TIP",
                      "worker_group": "1",
                      "description": "Payout Description",
                      "display_header_label": null,
                      "display_sub_label": null,
                      "status": "CANCELED",
                      "reason_code": null,
                      "payout": null,
                      "metadata": null,
                      "time_created": "2026-01-01T18:00:00Z",
                      "time_modified": null
                    }
                  },
                  "Reversed": {
                    "value": {
                      "worker_id": "123456",
                      "amount": 100,
                      "external_id": "090eaa89-77f6-4f06-b352-a8e8a277f966",
                      "type": "TIP",
                      "worker_group": "1",
                      "description": "Payout Description",
                      "display_header_label": null,
                      "display_sub_label": null,
                      "status": "REVERSED",
                      "reason_code": null,
                      "payout": {
                        "id": "98d656e9-6979-4777-b97c-f3f4b8b1a0e7",
                        "payment_type": "WALLET",
                        "amount": 100,
                        "fee": 0,
                        "org_paid_fee": 0,
                        "org_charged_fee": 0,
                        "time_completed": "2026-01-01T18:00:10Z"
                      },
                      "metadata": null,
                      "time_created": "2026-01-01T18:00:00Z",
                      "time_modified": null
                    }
                  }
                }
              }
            }
          },
          "201": {
            "description": "Returned if an attempt to disburse funds was successful. This can occur if the disbursement is new or if it already exists and is retried successfully.\n",
            "content": {
              "application/json": {
…

Documentation search

Search Documentation

searchread-only

Searches through documentation with the given search query, returning a list of results with ID, title, and URL.

Read-only · No side effects · Branch docs only

📘

Short keyword queries (one to three words) work best. Longer, natural-language queries can return fewer results or none.

Parameters

  • query string · required
    search query

Returns: A list of matching guide pages, each with an id, title, and url. Pass an id to fetch to read the page.

Example prompt: "Find the Branch guide on disbursement errors."

Request

curl -X POST https://docs.branchapp.com/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"search","arguments":{"query":"disbursement"}}}'
# pip install "mcp>=2"
import asyncio
from mcp import Client

async def main():
    async with Client("https://docs.branchapp.com/mcp") as client:
        result = await client.call_tool("search", {"query": "disbursement"})
        print(result.content[0].text)

asyncio.run(main())
// npm install @modelcontextprotocol/sdk
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const client = new Client({ name: "my-app", version: "1.0.0" });
await client.connect(new StreamableHTTPClientTransport(new URL("https://docs.branchapp.com/mcp")));

const result = await client.callTool({ name: "search", arguments: { query: "disbursement" } });
console.log(result.content[0].text);
await client.close();

Response

{
  "result": [
    {
      "id": "branch-developer/docs/disbursement-create",
      "title": "Create a Disbursement",
      "url": "https://docs.branchapp.com/branch-developer/docs/disbursement-create"
    },
    {
      "id": "branch-developer/docs/disbursement-error-handling",
      "title": "Disbursement Error Handling",
      "url": "https://docs.branchapp.com/branch-developer/docs/disbursement-error-handling"
    },
    {
      "id": "branch-developer/docs/testing-disbursements",
      "title": "Testing Disbursements",
      "url": "https://docs.branchapp.com/branch-developer/docs/testing-disbursements"
    },
    "… 2 more"
  ]
}

Fetch Documentation Page

fetchread-only

Gets detailed content for documentation by ID returned from the search tool.

Read-only · No side effects · Branch docs only

Parameters

  • id string · required
    Canonical IDs use project/section/slug. Legacy project/slug, recipe:project/slug and ref:project/slug IDs are also accepted. For a link /<section>/<slug> the search tool did not return, use <project>/<section>/<slug>, with <project> taken from an ID this project already returned.

Returns: The full content of one documentation page, as Markdown.

Example prompt: "Read the Disbursement Error Handling guide and summarize the retryable errors."

Request

curl -X POST https://docs.branchapp.com/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"fetch","arguments":{"id":"branch-developer/docs/disbursement-error-handling"}}}'
# pip install "mcp>=2"
import asyncio
from mcp import Client

async def main():
    async with Client("https://docs.branchapp.com/mcp") as client:
        result = await client.call_tool("fetch", {"id": "branch-developer/docs/disbursement-error-handling"})
        print(result.content[0].text)

asyncio.run(main())
// npm install @modelcontextprotocol/sdk
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const client = new Client({ name: "my-app", version: "1.0.0" });
await client.connect(new StreamableHTTPClientTransport(new URL("https://docs.branchapp.com/mcp")));

const result = await client.callTool({ name: "fetch", arguments: { id: "branch-developer/docs/disbursement-error-handling" } });
console.log(result.content[0].text);
await client.close();

Response

Links in this page shaped `/<section>/<slug>`, like `/docs/<slug>` or `/<custom-section>/<slug>`, resolve against https://docs.branchapp.com/branch-developer/. Any first segment counts as a section, even one you do not recognize. Links shaped `/<version>/<section>/<slug>`, like `/v1.0/docs/<slug>`, resolve the same way, with the link's version in place of any version in that base. Other links that start with `/`, like `/<other-project>/docs/<slug>`, resolve against https://docs.branchapp.com/.

## Overview

When making payments to workers, robust handling of error cases is a necessity to ensure money is moved correctly. After using [Create Disbursement](ref:create-disbursement-v2), [check the HTTP response status code](doc:disbursement-error-handling#check-the-http-response-status-code) and the disbursement's `status` to determine followup actions.

- If a `200` or a `201` is returned, the request was successful and no action is required.
- If a `500`, a `504`, or a `202` with `status` = `PENDING` is returned, the request result is [temporarily uncertain and should be polled.](doc:disbursement-error-handling#poll-temporary-states-for-completion)
- If a `400` or a `429`  is returned, the request failed due to misconfiguration or rate limiting.
- If a `202` with `status` = `FAILED` is returned, the request failed and should be resolved before retrying the disbursement. [Check the `reason_code`](doc:disbursement-error-handling#check-the-reason-code) to determine resolution actions.
  - After confirming the disbursement `status` = `FAILED`, a disbursement can be safely [retried](doc:disbursement-error-handling#retry-a-disbursement) if desired.&#x20;

## Check the HTTP Response Status Code

<Table align={["left","left","left"]}>
  <thead>
    <tr>
      <th>
        Code
      </th>

      <th>
        Condition
      </th>

      <th>
        Actions
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        `200`
      </td>

      <td>
        A matching disbursement already exists, status is `CANCELED` or `SKIPPED`
      </td>

      <td>
        Can be [retried](doc:disbursement-error-handling#retry-a-disbursement) if `CANCELED`.<br />Can be [updated and reattempted](doc:disbursement-error-handling#skipped-disbursements) if `SKIPPED`.
      </td>
    </tr>

    <tr>
      <td>
        `201`
      </td>

      <td>
        A new disbursement was created, status is `SCHEDULED` or `COMPLETED`
      </td>

      <td>
        Can be [canceled](ref:cancel-disbursement-v2) if `SCHEDULED`.<br />Can be [updated and reattempted](doc:disbursement-error-handling#skipped-disbursements) or [reversed](ref:create-disbursement-reversal-v2) if `COMPLETED`.
      </td>
    </tr>

    <tr>
      <td>
        `202`
      </td>

      <td>
        A new disbursement was attempted, status is `PENDING` or `FAILED`
      </td>

      <td>
        Can be [polled](doc:disbursement-error-handling#pending-disbursements) if `PENDING`.<br />Can be [resolved](doc:disbursement-error-handling#failed-disbursements) then [retried](doc:disbursement-error-handling#retry-a-disbursement) if `FAILED`.
      </td>
    </tr>

    <tr>
      <td>
        `400`
      </td>

      <td>
        A static request validation is incorrect or no invoice configuration is found for the request
      </td>

      <td>
        If static request validation failed, inspect the response and fix the request accordingly.

        If no invoice configuration was found, then contact Support or your Account Manager.
      </td>
    </tr>

    <tr>
      <td>
        `429`
      </td>

      <td>
        [Too many actual requests are being sent](doc:rate-limits#endpoints-with-additional-rate-limit-restrictions) to the API, or the org has [exceeded their daily disbursement limit](ref:create-disbursement-v2#response-schemas).
      </td>

      <td>
        If rate-limited, [handle by waiting with exponential backoff](doc:rate-limits#handling). <br />Otherwise, contact Support or your Account Manager about potentially increasing the daily disbursement limit.
      </td>
    </tr>

    <tr>
      <td>
        `500`
      </td>

      <td>
        Unexpected Error
      </td>

      <td>
        [Poll to check if the error automatically resolves.](doc:disbursement-error-handling#poll-temporary-states-for-completion) If the problem persists, contact Support or your Account Manager with any additional information that can be provided.
      </td>
    </tr>

    <tr>
      <td>
…

Server configuration

Get Server Variables

get-server-variablesread-only

Gets the server variables for each server within a specific OpenAPI spec.

Read-only · No side effects · Branch docs only

Parameters

This tool takes no arguments.

Returns: The API base URLs from the OpenAPI spec: production (https://api.branchapp.com) and sandbox (https://sandbox.branchapp.com).

Example prompt: "What are the base URLs for the Branch sandbox and production APIs?"

Request

curl -X POST https://docs.branchapp.com/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get-server-variables","arguments":{}}}'
# pip install "mcp>=2"
import asyncio
from mcp import Client

async def main():
    async with Client("https://docs.branchapp.com/mcp") as client:
        result = await client.call_tool("get-server-variables", {})
        print(result.content[0].text)

asyncio.run(main())
// npm install @modelcontextprotocol/sdk
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const client = new Client({ name: "my-app", version: "1.0.0" });
await client.connect(new StreamableHTTPClientTransport(new URL("https://docs.branchapp.com/mcp")));

const result = await client.callTool({ name: "get-server-variables", arguments: {} });
console.log(result.content[0].text);
await client.close();

Response

[
  {
    "url": "https://api.branchapp.com",
    "variables": {}
  },
  {
    "url": "https://sandbox.branchapp.com",
    "variables": {}
  }
]

Webhooks

List Webhook Events

list-webhook-eventsread-only

Call this when the user asks about Branch webhooks, events, notifications, or callbacks — including which events exist, what data an event contains, or which event fires at a given point in worker onboarding or payment. Returns the complete catalog of all 22 Branch webhook events with their payload fields. Use the fetch tool with a listed doc id to get full details and a JSON example for a specific event.

Read-only · No side effects · Branch docs only

Parameters

This tool takes no arguments.

Returns: The full catalog of Branch webhook events, the shared event envelope, and the payload fields for each event, with links to the full reference.

Example prompt: "What webhook does Branch send when a worker finishes onboarding?"

Request

curl -X POST https://docs.branchapp.com/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list-webhook-events","arguments":{}}}'
# pip install "mcp>=2"
import asyncio
from mcp import Client

async def main():
    async with Client("https://docs.branchapp.com/mcp") as client:
        result = await client.call_tool("list-webhook-events", {})
        print(result.content[0].text)

asyncio.run(main())
// npm install @modelcontextprotocol/sdk
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const client = new Client({ name: "my-app", version: "1.0.0" });
await client.connect(new StreamableHTTPClientTransport(new URL("https://docs.branchapp.com/mcp")));

const result = await client.callTool({ name: "list-webhook-events", arguments: {} });
console.log(result.content[0].text);
await client.close();

Response

All Branch webhooks share a common envelope; the event-specific
payload is in `data`, which is sent encrypted:
  { "event": "WALLET_CREATED", "event_id": UUID,
    "client_type": "ORGANIZATION", "client_id": "100000",
    "data": { ... } }
Setup: branch-developer/webhook-implementation
Retries: branch-developer/webhook-retries

All 22 Branch webhook events:

ACCOUNT_REVIEW
  Triggered when a worker has been flagged for manual review
  fields: employee_id, onboarding_link
  doc id: branch-developer/account-review

ACCOUNT_VERIFIED_AS_WORKER
  This webhook is triggered when a worker is verified on an
  organization's roster. Routing and account number will return null
  if the worker's wallet has not yet been created.
  fields: employee_id, account_number, routing_number
  doc id: branch-developer/account-verified-as-worker

ADVANCE_ADJUSTMENT
  Triggered when an adjustment is made to an advance
  fields: adjustment_amount, advance_id, employee_id,
  original_outstanding_amount, outstanding_amount, timestamp, type
  doc id: branch-developer/advance-adjustment

ADVANCE_CLAIMED
  Triggered when a worker claims an advance
  fields: advance_id, amount, employee_id, timestamp
  doc id: branch-developer/advance-claimed

CARD_ACTIVATED
  Triggered when a worker activates their card
  fields: employee_id, marqeta_card_token, card_product, card_type,
  time_emitted
  doc id: branch-developer/card-activated

CARD_DEACTIVATED
  Triggered when a worker deactivates their card
  fields: employee_id, marqeta_card_token, card_product, card_type,
  reason_code, time_emitted
  doc id: branch-developer/card-deactivated

DIRECT_ACCOUNT_CREATED
  This webhook is triggered when a worker completes onboarding for a
  Branch Direct Account.
  fields: worker_id
  doc id: branch-developer/branch-direct-account-created

DIRECT_DEPOSIT_CREATED
  This webhook is triggered when a Direct Deposit configuration is
  created for a worker's account.
  fields: employee_id, account_number, routing_number, amount,
  amount_type
  doc id: branch-developer/direct-deposit-created

EWA_ACCOUNT_VERIFIED
  This webhook is triggered when a worker's EWA Account is Verified.
  fields: worker_id
  doc id: branch-developer/ewa-account-verified

INVOICE_CREATED
  Triggered when an invoice is created
  fields: id, amount, description, filename, due_date
  doc id: branch-developer/invoice-created

INVOICE_TRANSFER_INITIATED
  Triggered when an invoice transfer is initiated
  fields: invoice_id, amount, description
  doc id: branch-developer/invoice-transfer-initiated

KYC_DECLINED
  This webhook is triggered when a worker's KYC is declined.
  fields: employee_id, reason
  doc id: branch-developer/kyc-declined

KYC_FALLBACK_FAILED
  This webhook is triggered when KYC fallback ID upload verification
  has failed. This means that the worker is not payable through
  Branch.
  fields: employee_id
  doc id: branch-developer/kyc-fallback-failed

PAYMENT_PROFILE_ACTIVATED
  This webhook is triggered when a payment method is added to a
  worker's account.
  fields: employee_id, active_type, wallet, time_emitted
  doc id: branch-developer/payment-profile-activated

PAYMENT_PROFILE_DEACTIVATED
  This webhook is triggered when a payment method has been removed
  from a worker’s account, and the worker is no longer able to receive
  a disbursement.
  fields: employee_id, time_emitted
  doc id: branch-developer/payment-profile-deactivated

TIN_VERIFICATION_FAILED
  Triggered when a worker's TIN Verification request results in a
  mismatch
  fields: worker_id, status, timestamp
  doc id: branch-developer/tin-verification-failed

TIN_VERIFICATION_MATCHED
  Triggered when a worker's TIN Verification request results in a
  successful match
  fields: worker_id, timestamp
  doc id: branch-developer/tin-verification-matched

WALLET_ACTIVATED
  When a worker's identity is verified a wallet is created. It is not
  usable however until the worker passes additional KYC checks. When
  the KYC checks pass, this webhook is triggered.
  fields: employee_id, account_number, routing_number,
  onboarding_link, is_claimed
  doc id: branch-developer/wallet-activated

WALLET_CLAIMED
  Triggered when a worker downloads the application and claims a
…

How requests work

MCP clients handle this for you. If you're building your own client, each request is a JSON-RPC 2.0 message sent as an HTTP POST to the server URL. MCP uses POST for every message, including read-only ones. The Accept header must include both application/json and text/event-stream, or the server responds with 406 Not Acceptable.

List the tools:

curl -X POST https://docs.branchapp.com/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'

To call a tool, send "method": "tools/call" with the tool name and its arguments, as in the examples above. A client normally sends an initialize message first to start the session.

Accessing the MCP server URL using a browser is not supported and will return an error message. Browsers view pages using GET requests, and the MCP server only answers POST requests.