/api/v1/accountsList accounts
NORTHSTAR / API v1.0.0
Connect accounts, work and projects to your stack. Scoped credentials, predictable responses and signed events.
OpenAPI 3.1.1 · JSON ↗Use an API key or OAuth access token. Each credential binds one actor, workspace and demo generation; scopes and current permissions limit access.
GET /api/v1/accounts
Authorization: Bearer <token>Every write requires a key and generation. After a timeout or response_unknown, reuse the exact key and body. Changing input with the same key returns 409. Tickets use their credential generation.
Idempotency-Key: work-request-001
{"generation": <current-generation>, "status": "resolved"}Lists return data and nextCursor. Send that cursor to continue; limit accepts 1–100 (default 20). A changed snapshot returns 409: restart pagination.
GET /api/v1/accounts?limit=20&cursor=<nextCursor>120 authenticated requests per minute and credential. Rejected requests also consume quota. On 429, wait the number of seconds in Retry-After before retrying.
HTTP 429
Retry-After: 60Authorization code + S256 PKCE, explicit consent and an exact redirect URI. Exchange codes once; save the new refresh token after each rotation. Revoke a family to end its access.
GET /api/oauth/authorize
POST /api/oauth/token
POST /api/oauth/revokeDeduplicate by event ID. Verify HMAC SHA-256 over timestamp + "." + the original body, with a five-minute window. Five attempts, with 1/2/4/8-second backoff. Replay preserves the event ID.
Northstar-Event-Id: evt_<id>
Northstar-Signature: t=<timestamp>,v1=<signature>/api/v1/accountsList accounts
/api/v1/accounts/{id}Get accounts
/api/v1/accounts/{id}Update account name or notes
{
"type": "object",
"properties": {
"generation": {
"type": "integer",
"minimum": 1
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"notes": {
"type": "string",
"maxLength": 4000
}
},
"required": [
"generation"
],
"additionalProperties": false
}/api/v1/workList work
/api/v1/work/{id}Get work
/api/v1/workCreate a work request
{
"type": "object",
"properties": {
"generation": {
"type": "integer",
"minimum": 1
},
"accountId": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[A-Za-z0-9_-]+$"
},
"title": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"description": {
"type": "string",
"minLength": 1,
"maxLength": 4000
},
"priority": {
"type": "string",
"enum": [
"P1",
"P2",
"P3"
]
}
},
"required": [
"generation",
"accountId",
"title",
"description",
"priority"
],
"additionalProperties": false
}/api/v1/work/{id}Update work status or assignee
{
"type": "object",
"properties": {
"generation": {
"type": "integer",
"minimum": 1
},
"status": {
"type": "string",
"enum": [
"open",
"pending-customer",
"escalated",
"resolved"
]
},
"assigneeId": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[A-Za-z0-9_-]+$"
}
},
"required": [
"generation"
],
"additionalProperties": false
}/api/v1/projectsList projects
/api/v1/projects/{id}Get projects
/api/v1/projectsCreate project
{
"type": "object",
"properties": {
"generation": {
"type": "integer",
"minimum": 1
},
"accountId": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[A-Za-z0-9_-]+$"
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"ownerId": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[A-Za-z0-9_-]+$"
},
"dueAt": {
"type": "string",
"format": "date-time"
},
"nextMilestone": {
"type": "string",
"minLength": 1,
"maxLength": 200
}
},
"required": [
"generation",
"accountId",
"name",
"ownerId",
"dueAt",
"nextMilestone"
],
"additionalProperties": false
}/api/v1/projects/{id}Edit project
{
"type": "object",
"properties": {
"generation": {
"type": "integer",
"minimum": 1
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"ownerId": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[A-Za-z0-9_-]+$"
},
"dueAt": {
"type": "string",
"format": "date-time"
},
"nextMilestone": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"status": {
"type": "string",
"enum": [
"active",
"blocked",
"at-risk",
"complete"
]
}
},
"required": [
"generation",
"name",
"ownerId",
"dueAt",
"nextMilestone",
"status"
],
"additionalProperties": false
}/api/v1/projects/{id}Delete project (admin)
{
"type": "object",
"properties": {
"generation": {
"type": "integer",
"minimum": 1
}
},
"required": [
"generation"
],
"additionalProperties": false
}/api/v1/membersList members
/api/v1/members/{id}Get members
/api/v1/membersInvite member
{
"type": "object",
"properties": {
"generation": {
"type": "integer",
"minimum": 1
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"email": {
"type": "string",
"pattern": "^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$",
"maxLength": 254
},
"role": {
"type": "string",
"enum": [
"admin",
"member",
"viewer"
]
}
},
"required": [
"generation",
"name",
"email",
"role"
],
"additionalProperties": false
}/api/v1/invoicesList invoices
/api/v1/invoices/{id}Get invoices
/api/v1/invoicesSave invoice draft
{
"type": "object",
"properties": {
"generation": {
"type": "integer",
"minimum": 1
},
"accountId": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[A-Za-z0-9_-]+$"
},
"amount": {
"type": "number",
"minimum": 0.01,
"maximum": 10000000
},
"dueAt": {
"type": "string",
"format": "date-time"
}
},
"required": [
"generation",
"accountId",
"amount",
"dueAt"
],
"additionalProperties": false
}/api/v1/operationsList operations
/api/v1/operations/{id}Get operations
/api/v1/operations/{id}/downloadDownload a completed redacted export
/api/v1/operationsStart asynchronous redacted workspace export
{
"type": "object",
"properties": {
"generation": {
"type": "integer",
"minimum": 1
},
"type": {
"type": "string",
"enum": [
"export-workspace"
]
}
},
"required": [
"generation",
"type"
],
"additionalProperties": false
}/api/v1/webhook-deliveriesList webhook-deliveries
/api/v1/webhook-deliveries/{id}Get webhook-deliveries
/api/v1/webhook-deliveries/{id}/replayReplay a webhook with its original event ID
{
"type": "object",
"properties": {
"generation": {
"type": "integer",
"minimum": 1
}
},
"required": [
"generation"
],
"additionalProperties": false
}/healthAuthenticated connector health
/entitlements/{id}Plan and SSO for signed workspace external ID
/ticketsCreate support ticket; credential generation is its immutable precondition
{
"type": "object",
"properties": {
"subject": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"body": {
"type": "string",
"minLength": 1,
"maxLength": 8000
},
"requester_email": {
"type": "string",
"maxLength": 254
},
"page_url": {
"type": "string",
"maxLength": 2048
}
},
"required": [
"subject",
"body",
"requester_email"
],
"additionalProperties": false
}Errors use a stable code. A 503 or 504 does not confirm whether a write completed: recover its original result before starting another request.
{"error":{"code":"validation"}}| HTTP | Meaning / next step |
|---|---|
| 401 | Authentication required or expired |
| 403 | Insufficient scope or role |
| 404 | Resource not found |
| 409 | Generation, snapshot or idempotency conflict |
| 422 | Invalid request body |
| 429 | Quota exceeded; respect Retry-After |
| 500 | Redacted internal failure |
| 503 | Unknown result; recover the original request |
| 504 | Timeout; completion is not confirmed |