Bits
Bits are the executable units of work within a chain. They support multiple views: tree, matrix, calendar, and gantt.
Endpoints
| Method | Path | Description | Auth | Rate Limit |
|---|---|---|---|---|
| GET | /bits | List bits (supports ?chainId and filters) | JWT | 60/min |
| GET | /bits/tree | Hierarchy tree view | JWT | 30/min |
| GET | /bits/matrix | Matrix view | JWT | 30/min |
| GET | /bits/calendar | Calendar view | JWT | 30/min |
| GET | /bits/gantt | Global gantt view | JWT | 30/min |
| GET | /bits/gantt/:chainyId | Chainy-scoped gantt view | JWT | 30/min |
| GET | /bits/by-chain/:chainId | List bits by chain | JWT | 60/min |
| GET | /bits/:id | Get a single bit | JWT | 60/min |
| POST | /bits | Create a bit | JWT | 30/min |
| POST | /bits/insert-all | Bulk create bits | JWT | 10/min |
| PATCH | /bits/:id | Update a bit | JWT | 30/min |
| DELETE | /bits/:id | Delete a bit | JWT | 30/min |
| POST | /bits/:id/execute | Execute a bit through AI | JWT + Entitlement | 30/min |
| GET | /bits/:id/context | Çalıştırma bağlamına ekli dosyaları listele | JWT | — |
| POST | /bits/:id/context/files | Okunabilir bir File'ı çalıştırma bağlamına ekle | JWT | — |
| DELETE | /bits/:id/context/files/:fileId | Bir bağlam File'ını kaldır | JWT | — |
Bit Çalıştırma Bağlamı
Bir File içeriğinin Bit'in AI çalıştırması sırasında kullanılmasını istiyorsanız mevcut File'ı bağlayın. File erişim kuralları uygulanmaya devam eder; bağlamak okuma erişimini genişletmez.
Bağlama 201 Created, listeleme ve kaldırma 200 OK döndürür. Var olmayan veya çağıran tarafından okunamayan File için 404 döner. Okunabilir fakat yazılamayan bir Bit'in bağlamı değiştirilemez.
Create Bit
Request
| Field | Type | Required | Description |
|---|---|---|---|
title | string | Yes | Bit title (1-500 chars) |
chainId | string | Yes | Parent chain ID |
description | string | No | Detailed description |
priority | string | No | low, medium, high, urgent |
dueDate | string | No | ISO 8601 due date |
estimatedMinutes | number | No | Estimated time in minutes |
parentBitId | string | No | Parent bit ID for nesting |
tags | string[] | No | Array of tag strings |
Response
{
"data": {
"id": "cm5bit001",
"title": "Study verb conjugations - present tense",
"chainId": "$CHAIN_ID",
"description": "Focus on regular -ar, -er, -ir verb conjugations",
"priority": "high",
"status": "pending",
"dueDate": "2026-03-18T23:59:59.000Z",
"estimatedMinutes": 30,
"parentBitId": null,
"tags": ["grammar", "verbs"],
"createdAt": "2026-03-17T11:00:00.000Z",
"updatedAt": "2026-03-17T11:00:00.000Z"
}
}Code Examples
Use the id from Create Chain's response (data.id) as $CHAIN_ID.
curl -X POST https://api.chainabit.com/api/v1/bits \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Study verb conjugations - present tense",
"chainId": "'"$CHAIN_ID"'",
"description": "Focus on regular -ar, -er, -ir verb conjugations",
"priority": "high",
"dueDate": "2026-03-18T23:59:59Z",
"estimatedMinutes": 30,
"tags": ["grammar", "verbs"]
}'const BASE_URL = process.env.BASE_URL;
const TOKEN = process.env.TOKEN;
const chainId = process.env.CHAIN_ID; // from a chain lookup / create-chain response
const response = await fetch(`${BASE_URL}/bits`, {
method: "POST",
headers: {
Authorization: `Bearer ${TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
title: "Study verb conjugations - present tense",
chainId,
description: "Focus on regular -ar, -er, -ir verb conjugations",
priority: "high",
dueDate: "2026-03-18T23:59:59Z",
estimatedMinutes: 30,
tags: ["grammar", "verbs"],
}),
});
const { data } = await response.json();import requests, os
chain_id = os.environ["CHAIN_ID"] # from a chain lookup / create_chain()'s response
response = requests.post(
f"{os.environ['BASE_URL']}/bits",
headers={"Authorization": f"Bearer {os.environ['TOKEN']}"},
json={
"title": "Study verb conjugations - present tense",
"chainId": chain_id,
"description": "Focus on regular -ar, -er, -ir verb conjugations",
"priority": "high",
"dueDate": "2026-03-18T23:59:59Z",
"estimatedMinutes": 30,
"tags": ["grammar", "verbs"],
},
)
data = response.json()["data"]Bulk Create Bits
Request
Reuses the same $CHAIN_ID as Create Bit above — all bits in one bulk insert go to the same chain.
Response
{
"data": [
{ "id": "cm5bit002", "title": "Practice listening comprehension", "status": "pending" },
{ "id": "cm5bit003", "title": "Write 5 sentences in Spanish", "status": "pending" },
{ "id": "cm5bit004", "title": "Read a news article in Spanish", "status": "pending" }
],
"meta": { "inserted": 3 }
}Code Examples
curl -X POST https://api.chainabit.com/api/v1/bits/insert-all \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"bits": [
{ "title": "Practice listening comprehension", "chainId": "'"$CHAIN_ID"'" },
{ "title": "Write 5 sentences in Spanish", "chainId": "'"$CHAIN_ID"'" },
{ "title": "Read a news article in Spanish", "chainId": "'"$CHAIN_ID"'" }
]
}'const BASE_URL = process.env.BASE_URL;
const TOKEN = process.env.TOKEN;
const chainId = process.env.CHAIN_ID; // from a chain lookup / create-chain response
const response = await fetch(`${BASE_URL}/bits/insert-all`, {
method: "POST",
headers: {
Authorization: `Bearer ${TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
bits: [
{ title: "Practice listening comprehension", chainId },
{ title: "Write 5 sentences in Spanish", chainId },
{ title: "Read a news article in Spanish", chainId },
],
}),
});
const { data } = await response.json();import requests, os
chain_id = os.environ["CHAIN_ID"] # from a chain lookup / create_chain()'s response
response = requests.post(
f"{os.environ['BASE_URL']}/bits/insert-all",
headers={"Authorization": f"Bearer {os.environ['TOKEN']}"},
json={
"bits": [
{"title": "Practice listening comprehension", "chainId": chain_id},
{"title": "Write 5 sentences in Spanish", "chainId": chain_id},
{"title": "Read a news article in Spanish", "chainId": chain_id},
]
},
)
data = response.json()["data"]Tree View
Request
- Headers:
Authorization: Bearer <token>
Response
{
"data": [
{
"id": "cm5bit001",
"title": "Study verb conjugations - present tense",
"children": [
{ "id": "cm5bit005", "title": "Regular -ar verbs", "children": [] }
]
}
]
}Code Examples
curl https://api.chainabit.com/api/v1/bits/tree \
-H "Authorization: Bearer $TOKEN"const BASE_URL = process.env.BASE_URL;
const TOKEN = process.env.TOKEN;
const response = await fetch(`${BASE_URL}/bits/tree`, {
headers: { Authorization: `Bearer ${TOKEN}` },
});
const { data } = await response.json();import requests, os
response = requests.get(
f"{os.environ['BASE_URL']}/bits/tree",
headers={"Authorization": f"Bearer {os.environ['TOKEN']}"},
)
data = response.json()["data"]Matrix View
Request
- Headers:
Authorization: Bearer <token>
Response
{
"data": {
"urgent_important": [
{ "id": "cm5bit001", "title": "Study verb conjugations - present tense" }
],
"not_urgent_important": [],
"urgent_not_important": [],
"not_urgent_not_important": []
}
}Code Examples
curl https://api.chainabit.com/api/v1/bits/matrix \
-H "Authorization: Bearer $TOKEN"const BASE_URL = process.env.BASE_URL;
const TOKEN = process.env.TOKEN;
const response = await fetch(`${BASE_URL}/bits/matrix`, {
headers: { Authorization: `Bearer ${TOKEN}` },
});
const { data } = await response.json();import requests, os
response = requests.get(
f"{os.environ['BASE_URL']}/bits/matrix",
headers={"Authorization": f"Bearer {os.environ['TOKEN']}"},
)
data = response.json()["data"]Calendar View
Request
- Headers:
Authorization: Bearer <token>
Response
{
"data": {
"2026-03-17": [
{ "id": "cm5bit001", "title": "Study verb conjugations - present tense", "dueDate": "2026-03-18T23:59:59.000Z" }
],
"2026-03-18": []
}
}Code Examples
curl https://api.chainabit.com/api/v1/bits/calendar \
-H "Authorization: Bearer $TOKEN"const BASE_URL = process.env.BASE_URL;
const TOKEN = process.env.TOKEN;
const response = await fetch(`${BASE_URL}/bits/calendar`, {
headers: { Authorization: `Bearer ${TOKEN}` },
});
const { data } = await response.json();import requests, os
response = requests.get(
f"{os.environ['BASE_URL']}/bits/calendar",
headers={"Authorization": f"Bearer {os.environ['TOKEN']}"},
)
data = response.json()["data"]Gantt View
Request
- Headers:
Authorization: Bearer <token>
The chainy-scoped variant takes a chainyId path param — use the id from Create Chainy's response (data.id) as $CHAINY_ID.
Response
{
"data": [
{
"id": "cm5bit001",
"title": "Study verb conjugations - present tense",
"startDate": "2026-03-17T00:00:00.000Z",
"dueDate": "2026-03-18T23:59:59.000Z",
"dependencies": []
}
]
}Code Examples
# Global gantt
curl https://api.chainabit.com/api/v1/bits/gantt \
-H "Authorization: Bearer $TOKEN"
# Chainy-scoped gantt
curl https://api.chainabit.com/api/v1/bits/gantt/$CHAINY_ID \
-H "Authorization: Bearer $TOKEN"const BASE_URL = process.env.BASE_URL;
const TOKEN = process.env.TOKEN;
const chainyId = process.env.CHAINY_ID; // from a chainy lookup / create-chainy response
// Global gantt
const response = await fetch(`${BASE_URL}/bits/gantt`, {
headers: { Authorization: `Bearer ${TOKEN}` },
});
const { data } = await response.json();
// Chainy-scoped gantt
const scopedResponse = await fetch(`${BASE_URL}/bits/gantt/${chainyId}`, {
headers: { Authorization: `Bearer ${TOKEN}` },
});import requests, os
headers = {"Authorization": f"Bearer {os.environ['TOKEN']}"}
chainy_id = os.environ["CHAINY_ID"] # from a chainy lookup / create_chainy()'s response
# Global gantt
response = requests.get(f"{os.environ['BASE_URL']}/bits/gantt", headers=headers)
data = response.json()["data"]
# Chainy-scoped gantt
scoped = requests.get(f"{os.environ['BASE_URL']}/bits/gantt/{chainy_id}", headers=headers)Bit Completion Events
Track completion of bits over time. Each event records when a bit was marked as done.
Endpoints
| Method | Path | Description | Auth | Rate Limit |
|---|---|---|---|---|
| GET | /bits/:bitId/events | List completion events for a bit | JWT | 60/min |
| GET | /chains/:chainId/events | List completion events for a chain | JWT | 60/min |
| POST | /bits/:bitId/events | Record a completion event | JWT | 30/min |
Record Completion Event
Request
| Field | Type | Required | Description |
|---|---|---|---|
completedAt | string | No | ISO 8601 timestamp |
notes | string | No | Optional completion notes |
durationMinutes | number | No | Actual time spent in minutes |
Response
{
"data": {
"id": "cm5evt001",
"bitId": "$BIT_ID",
"completedAt": "2026-03-17T14:30:00.000Z",
"notes": "Completed all present tense conjugations for -ar verbs",
"durationMinutes": 25,
"createdAt": "2026-03-17T14:30:00.000Z"
}
}Code Examples
Use the id from Create Bit's response (data.id) as $BIT_ID.
curl -X POST https://api.chainabit.com/api/v1/bits/$BIT_ID/events \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"completedAt": "2026-03-17T14:30:00Z",
"notes": "Completed all present tense conjugations for -ar verbs",
"durationMinutes": 25
}'const BASE_URL = process.env.BASE_URL;
const TOKEN = process.env.TOKEN;
const bitId = process.env.BIT_ID; // from a bit lookup / create-bit response
const response = await fetch(`${BASE_URL}/bits/${bitId}/events`, {
method: "POST",
headers: {
Authorization: `Bearer ${TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
completedAt: "2026-03-17T14:30:00Z",
notes: "Completed all present tense conjugations for -ar verbs",
durationMinutes: 25,
}),
});
const { data } = await response.json();import requests, os
bit_id = os.environ["BIT_ID"] # from a bit lookup / create_bit()'s response
response = requests.post(
f"{os.environ['BASE_URL']}/bits/{bit_id}/events",
headers={"Authorization": f"Bearer {os.environ['TOKEN']}"},
json={
"completedAt": "2026-03-17T14:30:00Z",
"notes": "Completed all present tense conjugations for -ar verbs",
"durationMinutes": 25,
},
)
data = response.json()["data"]List Events for a Chain
Request
Same $CHAIN_ID as in Create Bit above.
Response
{
"data": [
{
"id": "cm5evt001",
"bitId": "$BIT_ID",
"completedAt": "2026-03-17T14:30:00.000Z",
"durationMinutes": 25
}
],
"meta": { "total": 1 }
}Code Examples
curl https://api.chainabit.com/api/v1/chains/$CHAIN_ID/events \
-H "Authorization: Bearer $TOKEN"const BASE_URL = process.env.BASE_URL;
const TOKEN = process.env.TOKEN;
const chainId = process.env.CHAIN_ID; // from a chain lookup / create-chain response
const response = await fetch(`${BASE_URL}/chains/${chainId}/events`, {
headers: { Authorization: `Bearer ${TOKEN}` },
});
const { data } = await response.json();import requests, os
chain_id = os.environ["CHAIN_ID"] # from a chain lookup / create_chain()'s response
response = requests.get(
f"{os.environ['BASE_URL']}/chains/{chain_id}/events",
headers={"Authorization": f"Bearer {os.environ['TOKEN']}"},
)
data = response.json()["data"]Bit Execution Profiles
Execution profiles define how a bit should be executed.
Endpoints
| Method | Path | Description | Auth | Rate Limit |
|---|---|---|---|---|
| GET | /bits/:bitId/executions | List execution profiles | JWT | 60/min |
| POST | /bits/:bitId/executions | Create an execution profile | JWT | 30/min |
| PATCH | /bits/:bitId/executions/:id | Update a profile | JWT | 30/min |
| DELETE | /bits/:bitId/executions/:id | Delete a profile | JWT | 30/min |
Create Execution Profile
Request
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Profile type: timer, pomodoro, focus, freeform |
durationMinutes | number | No | Duration in minutes |
breakMinutes | number | No | Break duration |
rounds | number | No | Number of rounds |
Same $BIT_ID as in Record Completion Event above.
Response
{
"data": {
"id": "cm5exec01",
"bitId": "$BIT_ID",
"type": "pomodoro",
"durationMinutes": 25,
"breakMinutes": 5,
"rounds": 4,
"createdAt": "2026-03-17T11:30:00.000Z"
}
}Code Examples
curl -X POST https://api.chainabit.com/api/v1/bits/$BIT_ID/executions \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "pomodoro",
"durationMinutes": 25,
"breakMinutes": 5,
"rounds": 4
}'const BASE_URL = process.env.BASE_URL;
const TOKEN = process.env.TOKEN;
const bitId = process.env.BIT_ID; // from a bit lookup / create-bit response
const response = await fetch(`${BASE_URL}/bits/${bitId}/executions`, {
method: "POST",
headers: {
Authorization: `Bearer ${TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
type: "pomodoro",
durationMinutes: 25,
breakMinutes: 5,
rounds: 4,
}),
});
const { data } = await response.json();import requests, os
bit_id = os.environ["BIT_ID"] # from a bit lookup / create_bit()'s response
response = requests.post(
f"{os.environ['BASE_URL']}/bits/{bit_id}/executions",
headers={"Authorization": f"Bearer {os.environ['TOKEN']}"},
json={"type": "pomodoro", "durationMinutes": 25, "breakMinutes": 5, "rounds": 4},
)
data = response.json()["data"]Bit Relations
Define dependencies and relationships between bits.
Endpoints
| Method | Path | Description | Auth | Rate Limit |
|---|---|---|---|---|
| GET | /bits/:bitId/relations | List relations (supports ?relationType) | JWT | 60/min |
| POST | /bits/:bitId/relations/connect | Connect two bits | JWT | 30/min |
| POST | /bits/:bitId/relations/disconnect | Disconnect two bits | JWT | 30/min |
| DELETE | /bits/:bitId/relations/:id | Delete a relation | JWT | 30/min |
Connect Two Bits
Request
| Field | Type | Required | Description |
|---|---|---|---|
targetBitId | string | Yes | The bit to connect to |
relationType | string | Yes | blocks, blocked_by, relates_to, duplicates |
$BIT_ID is the source bit (see Create Bit); $TARGET_BIT_ID is the id of the other bit you want to connect it to.
Response
{
"data": {
"id": "cm5rel001",
"sourceBitId": "$BIT_ID",
"targetBitId": "$TARGET_BIT_ID",
"relationType": "blocks",
"createdAt": "2026-03-17T12:00:00.000Z"
}
}Code Examples
curl -X POST https://api.chainabit.com/api/v1/bits/$BIT_ID/relations/connect \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"targetBitId": "'"$TARGET_BIT_ID"'",
"relationType": "blocks"
}'const BASE_URL = process.env.BASE_URL;
const TOKEN = process.env.TOKEN;
const bitId = process.env.BIT_ID; // the source bit, from a bit lookup / create-bit response
const targetBitId = process.env.TARGET_BIT_ID; // the bit to connect it to
const response = await fetch(`${BASE_URL}/bits/${bitId}/relations/connect`, {
method: "POST",
headers: {
Authorization: `Bearer ${TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
targetBitId,
relationType: "blocks",
}),
});
const { data } = await response.json();import requests, os
bit_id = os.environ["BIT_ID"] # the source bit, from a bit lookup / create_bit()'s response
target_bit_id = os.environ["TARGET_BIT_ID"] # the bit to connect it to
response = requests.post(
f"{os.environ['BASE_URL']}/bits/{bit_id}/relations/connect",
headers={"Authorization": f"Bearer {os.environ['TOKEN']}"},
json={"targetBitId": target_bit_id, "relationType": "blocks"},
)
data = response.json()["data"]