API quickstart
Create your first task through the Stackly REST API in about five minutes, then subscribe to webhooks so your own tools hear about changes as they happen.
Introduction
The API is organised around REST. It accepts JSON request bodies, returns JSON responses and uses standard HTTP status codes. Every request is made over HTTPS to one base URL:
Authentication
Requests are authenticated with an API key. Create one from Settings → Security → API keys. Keys carry the same permissions as the person who created them, so create a dedicated member for integrations when you can.
Sending your API key
Pass the key in the Authorization header. Never put keys in URLs or front-end code.
curl https://api.stackly.example/v1/me \
-H "Authorization: Bearer YOUR_API_KEY"
Rotating keys
Create the new key first, deploy it, then revoke the old one. Revoked keys stop working immediately and requests return 401 Unauthorized.
Create a task
Tasks belong to a project. Send a POST request with a title and, optionally, an owner, a due date and a column.
const response = await fetch('https://api.stackly.example/v1/projects/prj_42/tasks', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.STACKLY_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
title: 'Write the launch announcement',
assignee: 'usr_maya',
due_on: '2026-09-30',
column: 'In review'
})
});
const task = await response.json();
console.log(task.id); // "tsk_8f2c1a"
A successful request returns 201 Created and the full task object:
{
"id": "tsk_8f2c1a",
"title": "Write the launch announcement",
"status": "open",
"column": "In review",
"assignee": "usr_maya",
"due_on": "2026-09-30",
"comments_count": 0,
"created_at": "2026-09-19T09:41:12Z"
}
Pagination
List endpoints return up to 50 items and a next_cursor. Pass it back as ?cursor= to fetch the next page. When next_cursor is null, you have everything.
Webhooks
Webhooks send an HTTP POST to your server when something changes in a workspace. Add an endpoint under Settings → Integrations → Webhooks and choose the events you want.
| Event | Sent when |
|---|---|
task.created | A task is created in any project you can see |
task.moved | A task changes column or status |
task.completed | A task is marked done |
comment.created | Someone comments on a task or doc |
Verifying signatures
Each delivery includes a Stackly-Signature header: an HMAC-SHA256 of the raw body using your endpoint secret. Compare it before trusting the payload.
import hmac, hashlib
def is_valid_signature(raw_body, header, secret):
expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
# compare_digest avoids leaking information through timing
return hmac.compare_digest(expected, header)
Rate limits
Each API key can make 120 requests per minute. Responses include RateLimit-Remaining and RateLimit-Reset headers. When you go over, you get 429 Too Many Requests; wait until the reset time and retry.
POST /v1/tasks/batch for up to 100 tasks per request.Errors
Errors return a JSON body with a machine-readable code and a human-readable message that says what to change.
| Status | Code | What to do |
|---|---|---|
| 400 | invalid_request | Check the fields named in the message |
| 401 | unauthorized | Send a valid API key in the Authorization header |
| 404 | not_found | Check the ID, and that the key can see this project |
| 429 | rate_limited | Wait until RateLimit-Reset, then retry |