# API Docs

REST API for bulk task ingestion from GitHub, n8n, Taskwarrior, markdown, and custom sources.

## API

### Project API

API keys are scoped per project. Use this project URL for integrations and automations.

#### Base URL:

`https://<project-ref>.supabase.co/functions/v1/public-api`

Project API URL:`https://<project-ref>.supabase.co/functions/v1/public-api/v1/projects/<project_id>`

### n8n

Connect n8n in 3 steps

1) Create API key with `tasks:write`. 2) Use `/tasks:bulk-upsert`. 3) Send payload + `Idempotency-Key`.

```
curl -X POST "https://<project-ref>.supabase.co/functions/v1/public-api/v1/projects/<project_id>/tasks:bulk-upsert" \
  -H "Authorization: Bearer <pj_live_...>" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: import-2026-02-27-001" \
  -d '{
  "source": "github",
  "items": [\
    {\
      "external_id": "gh-issue-314",\
      "title": "Fix API timeout in ingestion worker",\
      "type": "bug",\
      "status": "open",\
      "priority": "high",\
      "metadata": {\
        "provider": "github",\
        "repo": "org/repo",\
        "issue_number": 314,\
        "synced_at": "2026-02-27T13:42:03.507Z"\
      }\
    }\
  ]
}'
```

```
{
  "source": "github",
  "items": [\
    {\
      "external_id": "gh-issue-314",\
      "title": "Fix API timeout in ingestion worker",\
      "type": "bug",\
      "status": "open",\
      "priority": "high",\
      "metadata": {\
        "provider": "github",\
        "repo": "org/repo",\
        "issue_number": 314,\
        "synced_at": "2026-02-27T13:42:03.507Z"\
      }\
    }\
  ]
}
```

```
Required headers
- Authorization: Bearer <pj_live_...>
- Content-Type: application/json
- Idempotency-Key: <unique-key>
```

### Ingest target prerequisites

Ingestion requires at least one `zone_object` in the project. If the API returns `missing_ingest_target`, create your first map object in the project and run the request again.

```
missing_ingest_target
Project API ingest target is not configured.

insufficient_scope
Required scope is missing (tasks:write for bulk upsert).

invalid_payload
Body must be: {"source":"...","items":[...]}

invalid_jwt
Authorization header must be: Bearer <project_api_key>
```
