GetItDoneGetItDone Docs
API ReferenceTask dependencies

Record a blocker

POST
/v1/tasks/{task_id}/dependencies

Records that the task in the path is blocked by blocker_task_id — the SAME operation the MCP link_task_dependency tool executes. Recording a link that already exists succeeds unchanged (no duplicate row, no second webhook), so retries are safe. A link that would close a loop is REFUSED with 409 dependency_cycle: the graph a client reads is guaranteed acyclic. A task cannot block itself (400 validation_failed), and a blocker in another organization is indistinguishable from one that does not exist (404 resource_not_found). Answers the task's full dependency view, so the caller can see whether it is now blocked without a second call.

Authorization

bearerAuth
headerAuthorizationBearer <token>

A gid_ API key (Profile → API Keys) or an OAuth 2.1 access token.

Path Parameters

task_id*string

Task short id, e.g. T-123 (a bare 123 is also accepted on input).

Match^(?:T-)?[0-9]{1,12}$

Header Parameters

Idempotency-Key?string

Optional client-generated key (1-255 visible ASCII characters; a UUID works) making this POST safely retryable. Retrying with the SAME key and byte-identical body within 24h replays the stored first response (marked Idempotency-Replayed: true, never re-executed, never charged against quota). The same key with a different body answers 422 idempotency_key_reused; a retry racing the first execution answers 409 idempotency_in_progress. Omitting the header executes normally with no idempotency guarantee.

Length1 <= length <= 255

Request Body

application/json
  1. body

The blocker to record for the task in the path.

blocker_task_id*string

The task that must finish FIRST. It must be in the same organization as the task in the path.

Match^(?:T-)?[0-9]{1,12}$

Response Body

The task's dependencies after the link was recorded.

application/json
  1. response

Both directions of a task's blocker graph, one hop out, plus its derived blocked state.

task_id*string

The task this view is for.

Match^(?:T-)?[0-9]{1,12}$
is_blocked*boolean

DERIVED on every read: true when at least one entry in blocked_by is still open. Never a stored column and never written to the task's status — a blocked task keeps whatever status its owner set.

blocked_by_count*integer

How many tasks must finish first, open or not — blocked_by.length.

Range-9007199254740991 <= value <= 9007199254740991
blocking_count*integer

How many tasks wait on this one — blocking.length.

Range-9007199254740991 <= value <= 9007199254740991
blocked_by*array<>

Tasks that must finish before this one can be worked on, oldest link first.

blocking*array<>

Tasks waiting on this one, oldest link first — the other direction of the same edges.

Example Request
curl -X POST 'https://app.nowgetitdone.com/v1/tasks/T-123/dependencies' \  -H 'Content-Type: application/json' \  -d '{  "blocker_task_id": "T-123"}'
Example Response
{  "task_id": "T-123",  "is_blocked": true,  "blocked_by_count": 2,  "blocking_count": 1,  "blocked_by": [    {      "task_id": "T-123",      "title": "Ship the public API",      "status": "TODO",      "open": true    }  ],  "blocking": [    {      "task_id": "T-123",      "title": "Ship the public API",      "status": "TODO",      "open": true    }  ]}