CrewBench API
REST API for operators to integrate CrewBench with external tools.
Introduction
The CrewBench External API gives your team programmatic access to your company's pilot schedule and duty request workflow. You can use it to pull schedule data into third-party dispatch tools, read pending crew requests, and approve, decline, or modify them — the same actions available in the web and mobile apps.
The API uses REST conventions, accepts and returns JSON, and is authenticated with long-lived API keys you generate in your settings.
Authentication
Every request must include your API key in the Authorization header as a Bearer token.
Authorization: Bearer cbk_your_api_key_here
Requests without a valid key, or using a revoked key, receive a 401 Unauthorized response.
Generating API Keys
To create an API key:
- Log in to CrewBench and go to Settings → API.
- Enter a descriptive name (e.g., "Jeppesen integration") and click Generate Key.
- Copy the key immediately — it is shown only once and cannot be retrieved later.
- To revoke a key, click Revoke next to it in the API settings page.
Base URL & Versioning
All endpoints are prefixed with:
https://crewbench.io/api/v1/external
The current version is v1. The version is included in the URL; breaking changes will be released under a new version.
GET /schedule
Returns all active pilots in your company along with their duty schedule for the requested date range.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| start_date | string | Optional | Start of the date range. Format: YYYY-MM-DD. Defaults to today. |
| end_date | string | Optional | End of the date range. Format: YYYY-MM-DD. Defaults to today + 30 days. |
Example Request
curl -X GET "https://crewbench.io/api/v1/external/schedule?start_date=2026-10-01&end_date=2026-10-31" \
-H "Authorization: Bearer cbk_your_api_key"
Example Response
{
"schedule": [
{
"id": 42,
"name": "John Smith",
"role": "Captain",
"ioe": false,
"check_airman": true,
"duty_days": [
{
"date": "2026-10-05",
"duty_code": "ON",
"label": "On Duty",
"color": "#2563EB"
}
]
},
{
"id": 43,
"name": "Sarah Lee",
"role": "First Officer",
"ioe": true,
"check_airman": false,
"duty_days": []
}
],
"start_date": "2026-10-01",
"end_date": "2026-10-31"
}
Pilot fields
| Field | Type | Description |
|---|---|---|
| id | integer | Pilot's unique ID in CrewBench. |
| name | string | Full name. |
| role | string | One of: Captain, First Officer, Flight Attendant. |
| ioe | boolean | true if the pilot is currently on Initial Operating Experience. |
| check_airman | boolean | true if the pilot is a Check Airman. |
| duty_days | array | Duty assignments within the requested date range. |
GET /duty_requests
Returns all pending duty requests, regardless of who initiated them. This includes both crew-initiated requests (pilot asking the operator for a duty assignment) and operator-initiated requests (operator asking a pilot to accept a duty assignment).
Use the requires_action field to distinguish between the two: crew-initiated requests require you to approve, decline, or modify them; operator-initiated requests are awaiting the pilot's response and no action is needed from you.
Example Request
curl -X GET "https://crewbench.io/api/v1/external/duty_requests" \
-H "Authorization: Bearer cbk_your_api_key"
Example Response
{
"duty_requests": [
{
"id": 99,
"pilot_name": "Jane Doe",
"bench_pilot_id": 42,
"duty_code": "OFF",
"duty_code_label": "Day Off",
"dates": ["2026-10-10", "2026-10-11"],
"initiated_by": "crew",
"requires_action": true,
"pilot_message": "Family event",
"operator_message": null,
"created_at": "2026-10-03T14:22:00Z"
},
{
"id": 100,
"pilot_name": "John Smith",
"bench_pilot_id": 43,
"duty_code": "ON",
"duty_code_label": "On Duty",
"dates": ["2026-10-15"],
"initiated_by": "operator",
"requires_action": false,
"pilot_message": null,
"operator_message": "We need you on the 15th.",
"created_at": "2026-10-04T09:10:00Z"
}
]
}
Response fields
| Field | Type | Description |
|---|---|---|
| id | integer | Unique ID of the duty request. |
| pilot_name | string | Full name of the pilot. |
| bench_pilot_id | integer | Pilot's unique ID in CrewBench. |
| duty_code | string | Short duty code (e.g., OFF). |
| duty_code_label | string | Human-readable duty code label (e.g., Day Off). |
| dates | array of strings | Requested dates in YYYY-MM-DD format. |
| initiated_by | string | crew — pilot submitted this request; operator — your team sent this request to the pilot. |
| requires_action | boolean | true for crew-initiated requests (you need to approve, decline, or modify); false for operator-initiated requests (awaiting pilot response). |
| pilot_message | string or null | Message from the pilot. Present on crew-initiated requests. |
| operator_message | string or null | Message from your team. Present on operator-initiated requests. |
| created_at | string (ISO 8601) | When the request was created. |
POST /duty_requests/:id/approve
Approve a pending crew-submitted duty request. The request status is set to confirmed. Only applies to crew-initiated requests (requires_action: true).
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | integer | Required | The ID of the duty request to approve. |
Request Body (JSON)
| Field | Type | Required | Description |
|---|---|---|---|
| message | string | Optional | A message sent to the pilot with the decision. |
Example Request
curl -X POST "https://crewbench.io/api/v1/external/duty_requests/99/approve" \
-H "Authorization: Bearer cbk_your_api_key" \
-H "Content-Type: application/json" \
-d '{"message": "Approved. Enjoy your days off."}'
Example Response
{ "success": true }
POST /duty_requests/:id/decline
Decline a pending crew-submitted duty request. Only applies to crew-initiated requests (requires_action: true).
Request Body (JSON)
| Field | Type | Required | Description |
|---|---|---|---|
| message | string | Optional | Explanation sent to the pilot. |
Example Request
curl -X POST "https://crewbench.io/api/v1/external/duty_requests/99/decline" \
-H "Authorization: Bearer cbk_your_api_key" \
-H "Content-Type: application/json" \
-d '{"message": "We need full coverage that week."}'
Example Response
{ "success": true }
POST /duty_requests/:id/modify
Partially approve a crew-initiated request by specifying which of the requested dates are approved. Only applies to crew-initiated requests (requires_action: true).
Request Body (JSON)
| Field | Type | Required | Description |
|---|---|---|---|
| approved_dates | array of strings | Required | The subset of dates to approve. Format: YYYY-MM-DD. Must be non-empty. |
| message | string | Optional | Explanation sent to the pilot. |
Example Request
curl -X POST "https://crewbench.io/api/v1/external/duty_requests/99/modify" \
-H "Authorization: Bearer cbk_your_api_key" \
-H "Content-Type: application/json" \
-d '{"approved_dates": ["2026-10-10"], "message": "Only the 10th is possible."}'
Example Response
{ "success": true }
Error Responses
All errors return a JSON body with an error field describing the problem.
{ "error": "Unauthorized" }
| Status | Meaning |
|---|---|
| 401 | Missing, invalid, or revoked API key. |
| 404 | The requested resource was not found, or belongs to a different operator. |
| 422 | Invalid parameters (e.g., missing approved_dates on a modify request, or an unparseable date string). |
| 429 | Rate limit exceeded. See below. |
Rate Limits
The API is rate-limited to 60 requests per minute per API key. If you exceed this limit, you will receive a 429 Too Many Requests response. Wait one minute before retrying.