Cards API
Cards are the content units pushed to channels. Each card contains an ordered array of blocks.
Create Card
POST /api/v1/channels/{channelId}/cards
Creates a new card in the channel. Counts toward the 200 cards/day limit.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
blocks |
Block[] | Yes | Array of block objects (see Blocks) |
status |
string | No | Card status: "default", "success", "warning", "error", "pending" |
Example
curl -X POST /api/v1/channels/3f7a1b2c-.../cards \
-H "Authorization: Bearer ofd_your_key" \
-H "Content-Type: application/json" \
-d '{
"status": "success",
"blocks": [
{
"type": "text",
"content": "Order #1234 processed",
"size": "lg",
"bold": true
},
{
"type": "badge",
"label": "Completed",
"variant": "success"
},
{
"type": "kv",
"rows": [
{ "key": "Customer", "value": "Jane Smith" },
{ "key": "Total", "value": "$89.99" },
{ "key": "Items", "value": "3" }
]
},
{
"type": "button",
"buttons": [
{ "id": "view", "label": "View Order", "style": "primary" },
{ "id": "refund", "label": "Refund", "style": "danger" }
]
}
]
}'
Response `201 Created`
{
"id": "7c8d9e0f-...",
"channel_id": "3f7a1b2c-...",
"created_at": "2025-01-15T10:30:00Z"
}
Block IDs
Blocks can optionally include an id field. If omitted, a UUID is auto-generated. Block IDs are used when patching specific blocks later.
Update Card
PATCH /api/v1/channels/{channelId}/cards/{cardId}
Updates a card's status and/or patches specific blocks. Only blocks listed in the blocks array are modified; others remain unchanged.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
status |
string | No | New card status |
blocks |
PatchBlock[] | No | Array of block patch objects |
Block Patch Object
Each item in blocks specifies which block to update and what to change:
{
"id": "block-uuid",
"patch": { ...fields to update... }
}
The patch object contains only the fields you want to change within that block.
Patching a Text Block
curl -X PATCH /api/v1/channels/3f7a1b2c-.../cards/7c8d9e0f-... \
-H "Authorization: Bearer ofd_your_key" \
-H "Content-Type: application/json" \
-d '{
"blocks": [
{
"id": "text-block-id",
"patch": {
"content": "Order #1234 shipped!"
}
}
]
}'
Patching a Badge Block
{
"blocks": [
{
"id": "badge-block-id",
"patch": {
"label": "Shipped",
"variant": "success"
}
}
]
}
Patching KV Rows
KV blocks support an append_rows field to add new rows without overwriting existing ones:
{
"blocks": [
{
"id": "kv-block-id",
"patch": {
"append_rows": [
{ "key": "Tracking", "value": "1Z999AA1..." }
]
}
}
]
}
You can also overwrite all rows:
{
"patch": {
"rows": [
{ "key": "Status", "value": "Delivered" }
]
}
}
Patching Individual Buttons
Button blocks support patching individual buttons by their id:
{
"blocks": [
{
"id": "button-block-id",
"patch": {
"buttons": [
{
"id": "refund-btn",
"patch": {
"label": "Refunded",
"disabled": true,
"style": "secondary"
}
}
]
}
}
]
}
Updating Card Status
{
"status": "success"
}
Full Update Example
curl -X PATCH /api/v1/channels/3f7a1b2c-.../cards/7c8d9e0f-... \
-H "Authorization: Bearer ofd_your_key" \
-H "Content-Type: application/json" \
-d '{
"status": "success",
"blocks": [
{
"id": "badge-id",
"patch": { "label": "Delivered", "variant": "success" }
},
{
"id": "btn-block-id",
"patch": {
"buttons": [
{ "id": "track-btn", "patch": { "disabled": true } }
]
}
}
]
}'
Response `200 OK`
{
"id": "7c8d9e0f-...",
"channel_id": "3f7a1b2c-...",
"status": "success",
"blocks": [...],
"updated_at": "2025-01-15T11:00:00Z"
}
Delete Card
DELETE /api/v1/channels/{channelId}/cards/{cardId}
Permanently deletes a card. Associated interactions will have their card_id set to null.
Response `204 No Content`
No response body.
Card Status Reference
The status field controls the visual border/highlight color of the card:
| Value | Color | Use case |
|---|---|---|
"default" |
Neutral | Normal content |
"success" |
Green | Completed, approved, done |
"warning" |
Yellow | Needs attention, degraded |
"error" |
Red | Failed, rejected, critical |
"pending" |
Blue/Grey | In progress, waiting |
Realtime Updates
Card changes are pushed to subscribers via Supabase Realtime. Any browser viewing /c/{channelId} will automatically receive:
- New cards (inserts)
- Updated cards (updates via PATCH)
- Deleted cards (deletes)
No polling required — changes appear instantly in the UI.