GridCrew REST API v1

Ship integrations against a small, clear API.

Inspect a board's schema, create or update typed work, and deliver signed events to your systems.

POST/api/v1/boards/{boardId}/rows
{
  "name": "Release candidate QA",
  "values": {
    "Impact": "High",
    "Owner": "rita@example.com"
  }
}
201 Created · typed values validated
Quick start

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.

Authentication

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.

Endpoints

The complete v1 surface.

All paths below are relative to https://gridcrew.ai. The documentation mirrors the implemented route handlers.

GET/api/v1/boards

List boards

Returns every active board in the API key's organization, ordered by name.

Example response
{
  "boards": [
    {
      "id": "30000000-0000-4000-8000-000000000001",
      "name": "FMX Windows",
      "description": "Windows release quality",
      "createdAt": "2026-07-24T08:00:00.000Z"
    }
  ]
}
GET/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.

Example response
{
  "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
    }
  ]
}
GET/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.

Example response
{
  "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.
POST/api/v1/boards/{boardId}/rows

Create 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.

Request body
{
  "name": "Refund failed — order 8841",
  "groupId": "50000000-0000-4000-8000-000000000001",
  "values": {
    "Impact": "Critical",
    "Owner": "rita@example.com",
    "Affected Users": "1"
  }
}
Example response
{
  "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.
GET/api/v1/rows/{rowId}

Read a row

Returns one row and its typed values. Rows outside the key's organization return 404.

Example response
{
  "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": {}
  }
}
PATCH/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.

Request body
{
  "name": "Canon R100 capture regression",
  "values": {
    "Release Status": "Fixed"
  }
}
Example response
{
  "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.
GET/api/v1/webhooks

List webhooks

Lists outbound webhook subscriptions for the key's organization. The API key creator must still be an Organization Admin.

Example response
{
  "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
    }
  ]
}
POST/api/v1/webhooks

Create a webhook

Creates an HTTPS subscription and returns its signing secret exactly once. Private-network and redirect targets are rejected.

Request body
{
  "name": "Production event relay",
  "endpointUrl": "https://hooks.example.com/gridcrew",
  "eventTypes": ["row.*", "cell.*", "update.*"]
}
Example response
{
  "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.
GET/api/v1/webhooks/{webhookId}

Read a webhook

Returns one subscription with health timestamps, consecutive failures, and its latest delivery summary.

Example response
{
  "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"
  }
}
PATCH/api/v1/webhooks/{webhookId}

Update a webhook

Changes the supplied name, HTTPS endpoint, event filters, or enabled state.

Request body
{
  "eventTypes": ["*"],
  "enabled": true
}
Example response
{
  "webhook": {
    "id": "92000000-0000-4000-8000-000000000001",
    "eventTypes": ["*"],
    "enabled": true
  }
}
DELETE/api/v1/webhooks/{webhookId}

Disable a webhook

Soft-disables a subscription. Existing delivery history remains available.

Example response
HTTP 204 No Content
GET/api/v1/webhooks/{webhookId}/deliveries?limit=25&offset=0

List webhook deliveries

Returns recent attempts, HTTP response status, retry state, and errors for one webhook.

Example response
{
  "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.
POST/api/v1/webhooks/{webhookId}/test

Send a test webhook

Immediately attempts a signed `webhook.test` delivery and returns the recorded result.

Example response
{
  "delivery": {
    "id": "95000000-0000-4000-8000-000000000099",
    "eventType": "webhook.test",
    "status": "delivered",
    "attemptCount": 1,
    "responseStatus": 204,
    "lastError": null
  }
}
Typed values

Write the same values the product understands.

Column typeAccepted API value
TextString, up to the current 10,000-character limit.
NumericA decimal number or numeric string.
DateA parseable date, stored as YYYY-MM-DD.
StatusThe exact label of an active status option.
OwnerAn active organization member UUID or email.
Outbound webhooks

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.

Event payload
{
  "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
  }
}
Webhook security

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.

HeaderValue
x-gridcrew-webhook-idStable delivery UUID for idempotency.
x-gridcrew-webhook-eventEvent type, for example row.created.
x-gridcrew-webhook-timestampUnix timestamp used in the signature.
x-gridcrew-webhook-signaturev1= 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"
Delivery behavior

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.

Errors

Predictable JSON and matching HTTP status codes.

Errors return { "error": "Human-readable message." }. Validation messages name the offending column or value when possible.

400

Invalid JSON, a missing required field, or an invalid typed value.

401

The bearer API key is missing, invalid, or revoked.

403

Webhook management requires an active Organization Admin.

404

The requested record is outside the key's organization.

503

GridCrew could not complete the request against its data service.

Roadmap

Explicitly not part of v1 yet.

Per-key rate limits and scopes · Coming soon Row deletion · Coming soon Optimistic-concurrency preconditions · Coming soon Group and column management · Coming soon

Ready to connect your workflow?

Start free, create a workspace, then create API keys and webhooks from Board settings → Developer.

Create a workspace