The XRAY Task Inbox API lets you create, read, update, and triage tasks programmatically. All endpoints return JSON.
Authentication
Obtaining an API Key
API keys can be generated directly from the web interface:
- Sign in to the web app with your
@xray.tech account.
- Navigate to the Settings tab in the main navigation.
- Enter a name for your key (e.g. "Zapier Integration") and click Generate New Key.
- Copy the generated secret key. Keep it safe—it will not be shown again.
Note for Administrators: Global machine keys can still be hardcoded via the API_KEY_MAP environment variable if desired (format: key:email:Name).
Using Your API Key
Include the X-API-Key header in every request:
curl -H "X-API-Key: your-secret-key-here" \
-H "Content-Type: application/json" \
https://tasks.xray.tech/api/tasks
Web Authentication
Web users authenticate via Google OAuth. Sign in at the app root (/) with your @xray.tech account. The session cookie is sent automatically with browser requests.
Auth Check
GET /auth/me
Returns the current user or 401 if not authenticated.
// 200 OK
{ "user": { "email": "mark@xray.tech", "name": "Mark Campos" } }
// 401 Unauthorized
{ "error": "Not authenticated" }
Endpoints
GET /api/tasks
List inbox tasks (Status = "Backlog", Triage Status = "New") scoped to the authenticated user.
Example
curl -H "X-API-Key: your-key" https://tasks.xray.tech/api/tasks
Response
{
"tasks": [
{
"id": "recXXXXXXXXXXXXXX",
"title": "Update onboarding docs",
"description": "The onboarding guide needs updating for new hires",
"status": "Backlog",
"priority": "Normal",
"triageStatus": "New",
"origin": "Human",
"originDetail": "Mark via Slack",
"triageNotes": "",
"assignedTo": { "id": "usr...", "email": "mark@xray.tech", "name": "Mark Campos" },
"requestedBy": null,
"project": [],
"dueDate": null,
"startDate": null,
"hoursEstimated": null,
"hoursUsed": null,
"createdAt": "2026-03-10T14:30:00.000Z"
}
]
}
GET /api/tasks/:id
Get a single task by its Airtable record ID.
Example
curl -H "X-API-Key: your-key" https://tasks.xray.tech/api/tasks/recXXXXXXXXXXXXXX
Response
{ "task": { "id": "recXXXXXXXXXXXXXX", "title": "...", ... } }
POST /api/tasks
Create a new inbox task. Sets Status = "Backlog" and Triage Status = "New" automatically.
Request Body
| Field | Type | Required | Notes |
title | string | Yes | Max 120 characters |
description | string | No | Max 500 characters |
origin | string | No | Default: "Human". Options: Human, AI Agent, Automation |
originDetail | string | No | E.g., "Claude Code", "Zapier webhook" |
assignedTo | string | No | Email address. Defaults to authenticated user |
priority | string | No | Default: "Normal". Options: Normal, High, Urgent |
project | string | No | Airtable record ID of a project |
Example — Minimal
curl -X POST \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{"title": "Review Q1 metrics"}' \
https://tasks.xray.tech/api/tasks
Example — Full
curl -X POST \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{
"title": "Update client proposal",
"description": "Revise the SOW section with new pricing",
"origin": "AI Agent",
"originDetail": "Claude Code",
"priority": "High",
"assignedTo": "mark@xray.tech"
}' \
https://tasks.xray.tech/api/tasks
Response (201 Created)
{ "ok": true, "task": { "id": "recNEW...", "title": "Update client proposal", ... } }
Error Response (400)
{ "error": "Validation failed", "fields": { "title": "Required" } }
PATCH /api/tasks/:id
Partial update — only include fields you want to change.
Updatable Fields
| Field | Type | Notes |
title | string | |
description | string | |
priority | string | Normal, High, Urgent |
status | string | Backlog, In Progress, Done, etc. |
triageStatus | string | New, Accepted, Rejected, Needs More Info |
triageNotes | string | |
dueDate | string | Format: YYYY-MM-DD |
startDate | string | Format: YYYY-MM-DD |
hoursEstimated | number | |
assignedTo | string | Email address (e.g., someone@xray.tech) |
project | string | Airtable record ID |
originDetail | string | |
Example — Enrich a task
curl -X PATCH \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{
"dueDate": "2026-03-15",
"hoursEstimated": 4,
"priority": "High"
}' \
https://tasks.xray.tech/api/tasks/recXXXXXXXXXXXXXX
Example — Mark as done
curl -X PATCH \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{"status": "Done", "triageStatus": "Accepted"}' \
https://tasks.xray.tech/api/tasks/recXXXXXXXXXXXXXX
POST /api/tasks/:id/accept
Accept a task and link it to a project.
Request Body
| Field | Type | Required |
projectId | string | Yes |
Example
curl -X POST \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{"projectId": "recPROJECT123"}' \
https://tasks.xray.tech/api/tasks/recXXXXXXXXXXXXXX/accept
POST /api/tasks/:id/reject
Reject a task with a reason.
Request Body
| Field | Type | Required |
reason | string | Yes |
Example
curl -X POST \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{"reason": "Duplicate of existing task"}' \
https://tasks.xray.tech/api/tasks/recXXXXXXXXXXXXXX/reject
POST /api/tasks/:id/needs-info
Request more information before triaging.
Request Body
| Field | Type | Required |
note | string | Yes |
Example
curl -X POST \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{"note": "Which client is this for?"}' \
https://tasks.xray.tech/api/tasks/recXXXXXXXXXXXXXX/needs-info
GET /api/projects?q=search
Search projects by name (min 2 characters). Returns up to 10 matches.
Example
curl -H "X-API-Key: your-key" "https://tasks.xray.tech/api/projects?q=onboard"
Response
{ "projects": [{ "id": "recPROJECT123", "name": "Client Onboarding v2" }] }
GET /api/clients
List all clients in the system for contextual dropdowns or filtering.
Example
curl -H "X-API-Key: your-key" "https://tasks.xray.tech/api/clients"
Response
{ "clients": [{ "id": "recCLIENT123", "name": "ACME Corp" }] }
GET /api/meetings/recent
Fetch recent meetings. By default, it returns meetings you attended or created.
Parameters
| Param | Description |
all | Set to true to fetch all meetings globally. |
client | Airtable Client Record ID or Client Name string. |
start / end | ISO Date boundaries (e.g. 2025-01-01) |
Example
curl -H "X-API-Key: your-key" "https://tasks.xray.tech/api/meetings/recent?all=true&client=recCLIENT123"
Response
{
"meetings": [
{
"id": "recMEETING123",
"name": "Weekly Sync with ACME",
"date": "2026-03-25T10:00:00.000Z",
"duration": 3600,
"link": { "label": "View Transcript", "url": "https://otter.ai/..." },
"project": ["recPROJECT123"],
"projectName": ["ACME Q1 Deliverables"],
"client": ["recCLIENT123"],
"clientName": ["ACME Corp"],
"users": ["mark@xray.tech"],
"summary": "Discussed the new onboarding flow.",
"keyProgress": "Frontend components are complete.",
"decisionsMade": "We will use Bolt.js for the Slack app.",
"nextActions": "- Mark to finalize the API docs.\n- Jane to deploy to staging.",
"actionable": "# Raw Action Items Markdown..."
}
]
}
GET /health
Health check (no auth required).
{ "status": "ok", "timestamp": "2026-03-10T15:00:00.000Z" }