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/mcpSettings → Connectors → Add custom connector, then enter the server URL
https://docs.branchapp.com/mcp~/.cursor/mcp.json, or .cursor/mcp.json in a project
{
"mcpServers": {
"branch": {
"url": "https://docs.branchapp.com/mcp"
}
}
}Command Palette → MCP: Open User Configuration (mcp.json)
{
"servers": {
"branch": {
"type": "http",
"url": "https://docs.branchapp.com/mcp"
}
}
}~/.codeium/windsurf/mcp_config.json
{
"mcpServers": {
"branch": {
"serverUrl": "https://docs.branchapp.com/mcp"
}
}
}~/.gemini/settings.json
{
"mcpServers": {
"branch": {
"httpUrl": "https://docs.branchapp.com/mcp"
}
}
}For step-by-step setup and Claude Enterprise options, see MCP.
Tools
Branch Overview · Read-only
List API Endpoints · Read-only
Search API Endpoints · Read-only
Get Endpoint Details · Read-only
Search Documentation · Read-only
Fetch Documentation Page · Read-only
Get Server Variables · Read-only
List Webhook Events · Read-only
Agents typically chain them: search → fetch to read a guide, and search-endpoints → get-endpoint to look up an API operation.
Quickstart
Branch Overview
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
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
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
patternstring· 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
Gets detailed information about a specific API endpoint, including security schemes and servers
Read-only · No side effects · Branch docs only
Parameters
pathstring· required
The API endpoint path (e.g. /api/v1/users).methodstring· 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
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
querystring· 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
Gets detailed content for documentation by ID returned from the search tool.
Read-only · No side effects · Branch docs only
Parameters
idstring· 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. 
## 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
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
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.
Updated about 22 hours ago
