Make your first authenticated request.
Create an API key in Board settings → Developer. The plaintext key begins with gck_ and is shown once, so copy it into your secret manager before leaving the screen.
curl "https://gridcrew.ai/api/v1/boards" \
-H "Authorization: Bearer $GRIDCREW_API_KEY"Never put a GridCrew API key in browser code or a public repository. Call the API from a trusted server, worker, or script.
One revocable key, one organization boundary.
Bearer keys
Send Authorization: Bearer gck_… on every request.
Organization scoped
Records outside the key’s organization are never returned.
Attributed activity
Writes appear in activity under the member who created the key.
Immediate revocation
Revoking a key in settings prevents its next request.
The complete v1 surface.
All paths below are relative to https://gridcrew.ai. The documentation mirrors the implemented route handlers.
/api/v1/boardsList boards
Returns every active board in the API key's organization, ordered by name.
{
"boards": [
{
"id": "30000000-0000-4000-8000-000000000001",
"name": "FMX Windows",
"description": "Windows release quality",
"createdAt": "2026-07-24T08:00:00.000Z"
}
]
}/api/v1/boards/{boardId}Read a board schema
Returns the board's columns, active status labels, and groups so an integration can validate values before writing.
{
"board": {
"id": "30000000-0000-4000-8000-000000000001",
"name": "FMX Windows"
},
"columns": [
{
"id": "40000000-0000-4000-8000-000000000001",
"name": "Impact",
"type": "status",
"labels": ["Critical", "High", "Low", "Tiny"]
}
],
"groups": [
{
"id": "50000000-0000-4000-8000-000000000001",
"name": "Bugs",
"position": 1000
}
]
}/api/v1/boards/{boardId}/rows?limit=50&offset=0&groupId={optional}List rows
Returns rows in board order with their typed values. The response includes the total matching row count.
{
"total": 112,
"rows": [
{
"id": "80000000-0000-4000-8000-000000000001",
"name": "Canon R100 capture fails after 3rd shot",
"groupId": "50000000-0000-4000-8000-000000000001",
"version": 15,
"values": {
"40000000-0000-4000-8000-000000000001": {
"column": "Impact",
"type": "status",
"value": "Critical"
}
}
}
]
}- `limit` defaults to 50 and is clamped between 1 and 200.
- `offset` defaults to 0.
- `groupId` is optional and filters rows to one group.
/api/v1/boards/{boardId}/rowsCreate a row
Creates a row and validates values against the board's column types. Value keys may be column IDs or case-insensitive column names.
{
"name": "Refund failed — order 8841",
"groupId": "50000000-0000-4000-8000-000000000001",
"values": {
"Impact": "Critical",
"Owner": "rita@example.com",
"Affected Users": "1"
}
}{
"row": {
"id": "80000000-0000-4000-8000-000000000099",
"name": "Refund failed — order 8841",
"groupId": "50000000-0000-4000-8000-000000000001",
"version": 1,
"values": {
"40000000-0000-4000-8000-000000000001": {
"column": "Impact",
"type": "status",
"value": "Critical"
}
}
}
}- `groupId` is optional; the first group is used when omitted.
- Status values must match an active label.
- Owner values accept an organization member UUID or email.
- A successful request returns HTTP 201.
/api/v1/rows/{rowId}Read a row
Returns one row and its typed values. Rows outside the key's organization return 404.
{
"row": {
"id": "80000000-0000-4000-8000-000000000001",
"name": "Canon R100 capture fails after 3rd shot",
"groupId": "50000000-0000-4000-8000-000000000001",
"version": 15,
"createdAt": "2026-07-24T08:00:00.000Z",
"updatedAt": "2026-07-25T09:15:00.000Z",
"values": {}
}
}/api/v1/rows/{rowId}Update a row
Changes only the supplied name and values, validates typed cells, increments the row version, and records API activity.
{
"name": "Canon R100 capture regression",
"values": {
"Release Status": "Fixed"
}
}{
"row": {
"id": "80000000-0000-4000-8000-000000000001",
"name": "Canon R100 capture regression",
"version": 16,
"values": {
"40000000-0000-4000-8000-000000000006": {
"column": "Release Status",
"type": "status",
"value": "Fixed"
}
}
}
}- Only fields present in the body are changed.
- Optimistic-concurrency preconditions are not part of the public v1 contract yet.
/api/v1/webhooksList webhooks
Lists outbound webhook subscriptions for the key's organization. The API key creator must still be an Organization Admin.
{
"webhooks": [
{
"id": "92000000-0000-4000-8000-000000000001",
"name": "Production event relay",
"endpointUrl": "https://hooks.example.com/gridcrew",
"eventTypes": ["row.*", "cell.*"],
"secretPrefix": "gcwhsec_q5Y3",
"enabled": true,
"latestDelivery": null
}
]
}/api/v1/webhooksCreate a webhook
Creates an HTTPS subscription and returns its signing secret exactly once. Private-network and redirect targets are rejected.
{
"name": "Production event relay",
"endpointUrl": "https://hooks.example.com/gridcrew",
"eventTypes": ["row.*", "cell.*", "update.*"]
}{
"webhook": {
"id": "92000000-0000-4000-8000-000000000001",
"name": "Production event relay",
"endpointUrl": "https://hooks.example.com/gridcrew",
"eventTypes": ["row.*", "cell.*", "update.*"],
"enabled": true
},
"secret": "gcwhsec_q5Y3..."
}- Use `*` for every current and future event.
- Use namespace filters such as `row.*`, or exact events such as `row.created`.
- Store the returned secret immediately; it is never returned again.
- A successful request returns HTTP 201.
/api/v1/webhooks/{webhookId}Read a webhook
Returns one subscription with health timestamps, consecutive failures, and its latest delivery summary.
{
"webhook": {
"id": "92000000-0000-4000-8000-000000000001",
"name": "Production event relay",
"endpointUrl": "https://hooks.example.com/gridcrew",
"eventTypes": ["row.*", "cell.*"],
"enabled": true,
"consecutiveFailures": 0,
"lastSuccessAt": "2026-07-25T08:30:00.000Z"
}
}/api/v1/webhooks/{webhookId}Update a webhook
Changes the supplied name, HTTPS endpoint, event filters, or enabled state.
{
"eventTypes": ["*"],
"enabled": true
}{
"webhook": {
"id": "92000000-0000-4000-8000-000000000001",
"eventTypes": ["*"],
"enabled": true
}
}/api/v1/webhooks/{webhookId}Disable a webhook
Soft-disables a subscription. Existing delivery history remains available.
HTTP 204 No Content/api/v1/webhooks/{webhookId}/deliveries?limit=25&offset=0List webhook deliveries
Returns recent attempts, HTTP response status, retry state, and errors for one webhook.
{
"total": 1,
"deliveries": [
{
"id": "95000000-0000-4000-8000-000000000001",
"eventType": "row.created",
"status": "delivered",
"attemptCount": 1,
"responseStatus": 204,
"lastError": null,
"deliveredAt": "2026-07-25T08:30:00.000Z"
}
]
}- `limit` defaults to 25 and is clamped between 1 and 100.
- `offset` defaults to 0.
/api/v1/webhooks/{webhookId}/testSend a test webhook
Immediately attempts a signed `webhook.test` delivery and returns the recorded result.
{
"delivery": {
"id": "95000000-0000-4000-8000-000000000099",
"eventType": "webhook.test",
"status": "delivered",
"attemptCount": 1,
"responseStatus": 204,
"lastError": null
}
}Write the same values the product understands.
| Column type | Accepted API value |
|---|---|
| Text | String, up to the current 10,000-character limit. |
| Numeric | A decimal number or numeric string. |
| Date | A parseable date, stored as YYYY-MM-DD. |
| Status | The exact label of an active status option. |
| Owner | An active organization member UUID or email. |
Receive an event when GridCrew work changes.
Organization Admins can create HTTPS subscriptions from Board settings or through the v1 API. Subscribe to every event with *, a namespace such as row.*, or an exact event such as row.created.
Available namespaces include row, rows, cell, owner, update, reply, board, table, view, group, column, folder, widget, and membership events.
{
"id": "e6a76f07-8ff0-4fca-9d81-fef507a85b19",
"type": "row.created",
"createdAt": "2026-07-25T08:30:00.000Z",
"organizationId": "10000000-0000-4000-8000-000000000001",
"data": {
"boardId": "30000000-0000-4000-8000-000000000001",
"rowId": "80000000-0000-4000-8000-000000000099",
"actorId": "20000000-0000-4000-8000-000000000001",
"category": "row",
"summary": "Created row: Release candidate QA",
"before": null,
"after": null
}
}Verify the exact request body before processing it.
GridCrew signs {timestamp}.{rawBody} with HMAC SHA-256. Compare the resulting hex digest with x-gridcrew-webhook-signature, which uses the v1= prefix. Reject stale timestamps in your handler to reduce replay risk.
| Header | Value |
|---|---|
| x-gridcrew-webhook-id | Stable delivery UUID for idempotency. |
| x-gridcrew-webhook-event | Event type, for example row.created. |
| x-gridcrew-webhook-timestamp | Unix timestamp used in the signature. |
| x-gridcrew-webhook-signature | v1= followed by the HMAC SHA-256 hex digest. |
# Capture these values from the incoming request.
timestamp="$X_GRIDCREW_WEBHOOK_TIMESTAMP"
received="${X_GRIDCREW_WEBHOOK_SIGNATURE#v1=}"
expected="$(printf '%s.%s' "$timestamp" "$RAW_BODY" |
openssl dgst -sha256 -hmac "$GRIDCREW_WEBHOOK_SECRET" -hex |
sed 's/^.* //')"
test "$received" = "$expected"Durable queueing, bounded retries, visible results.
A 2xx response marks a delivery successful. Network failures, redirects, timeouts, and non-2xx responses retry after 1 minute, 5 minutes, 30 minutes, 2 hours, and 12 hours. After six failed attempts the delivery moves to dead_letter.
Delivery history includes the attempt count, response status, latest error, and final timestamp. Use the test endpoint to send an immediate signed webhook.test event.
Predictable JSON and matching HTTP status codes.
Errors return { "error": "Human-readable message." }. Validation messages name the offending column or value when possible.
400Invalid JSON, a missing required field, or an invalid typed value.
401The bearer API key is missing, invalid, or revoked.
403Webhook management requires an active Organization Admin.
404The requested record is outside the key's organization.
503GridCrew could not complete the request against its data service.
Explicitly not part of v1 yet.
Ready to connect your workflow?
Start free, create a workspace, then create API keys and webhooks from Board settings → Developer.
Create a workspace