Developer documentation

Tickably REST API

Manage Tickably through a conventional JSON API. Calls act as your user and keep your existing admin, user or client permissions.

Getting started

  1. Open Your profile.
  2. Generate credentials under API access.
  3. Save the secret when shown. Tickably cannot show it again.
  4. List projects, then use a returned project_id.

Base URL

https://api.tickably.com/v1

Only active projects you belong to are returned. Archived projects and secret shares are unavailable through this API.

Authentication

Send key and secret with every request.

X-API-Key: tk_live_...
X-API-Secret: tk_secret_...

HTTP Basic also works. Use API key as username and API secret as password.

curl https://api.tickably.com/v1/projects \
  -u "$TICKABLY_API_KEY:$TICKABLY_API_SECRET"
Keep secret server-side. Regenerating or disabling credentials invalidates existing access immediately.

Create a client project

This flow creates a project for a selected company, invites someone, then adds that person to the project.

1. List companies

curl https://api.tickably.com/v1/organizations \
  -H "X-API-Key: $TICKABLY_API_KEY" \
  -H "X-API-Secret: $TICKABLY_API_SECRET"

Use an organization_id where can_create_projects is true.

2. Create project

curl -X POST https://api.tickably.com/v1/organizations/12/projects \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $TICKABLY_API_KEY" \
  -H "X-API-Secret: $TICKABLY_API_SECRET" \
  -d '{
    "name": "Client website",
    "description": "Website support and development"
  }'

List and manage company projects

Use state=all, state=active or state=archived. Default: all.

curl "https://api.tickably.com/v1/organizations/12/projects?state=all" \
  -H "X-API-Key: $TICKABLY_API_KEY" \
  -H "X-API-Secret: $TICKABLY_API_SECRET"

curl -X PATCH https://api.tickably.com/v1/organizations/12/projects/42 \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $TICKABLY_API_KEY" \
  -H "X-API-Secret: $TICKABLY_API_SECRET" \
  -d '{
    "name": "Client website 2026",
    "description": "Website support and development",
    "archived": false
  }'

Archived projects stay readable. Only {"archived": false} can change an archived project. Unarchive it before other changes or permanent deletion.

curl -X DELETE https://api.tickably.com/v1/organizations/12/projects/42 \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $TICKABLY_API_KEY" \
  -H "X-API-Secret: $TICKABLY_API_SECRET" \
  -d '{"name": "Client website 2026"}'

Permanent deletion requires the exact current project name.

3. Invite person

curl -X POST https://api.tickably.com/v1/organizations/12/invitations \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $TICKABLY_API_KEY" \
  -H "X-API-Secret: $TICKABLY_API_SECRET" \
  -d '{
    "name": "Jamie Client",
    "email": "jamie@example.com",
    "company_admin": false
  }'

The response contains user.user_id. New people receive a password setup email. Existing Tickably users receive a company invitation. Pending invitees can already be assigned to a project, but get access only after accepting the company invitation.

4. Add person to project

curl -X POST https://api.tickably.com/v1/projects/42/members \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $TICKABLY_API_KEY" \
  -H "X-API-Secret: $TICKABLY_API_SECRET" \
  -d '{"user_id": 17, "role": "client"}'

Available project roles: admin, user, client.

Change or remove member

curl -X PATCH https://api.tickably.com/v1/projects/42/members/17 \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $TICKABLY_API_KEY" \
  -H "X-API-Secret: $TICKABLY_API_SECRET" \
  -d '{"role": "user"}'

curl -X DELETE https://api.tickably.com/v1/projects/42/members/17 \
  -H "X-API-Key: $TICKABLY_API_KEY" \
  -H "X-API-Secret: $TICKABLY_API_SECRET"

Tickets

List and filter

curl "https://api.tickably.com/v1/projects/42/tickets?status=pending&search=invoice" \
  -H "X-API-Key: $TICKABLY_API_KEY" \
  -H "X-API-Secret: $TICKABLY_API_SECRET"

Supported filters: status, category, phase, search, source and include_archived=true. Every project and ticket result includes a browser-ready url.

Create

curl -X POST https://api.tickably.com/v1/projects/42/tickets \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $TICKABLY_API_KEY" \
  -H "X-API-Secret: $TICKABLY_API_SECRET" \
  -d '{
    "title": "Invoice export fails",
    "description": "Export stops after processing.",
    "priority": "high",
    "assigned_to": 17,
    "due_date": "2026-08-14"
  }'

Update

curl -X PATCH https://api.tickably.com/v1/projects/42/tickets/184 \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $TICKABLY_API_KEY" \
  -H "X-API-Secret: $TICKABLY_API_SECRET" \
  -d '{"status": "in_progress", "estimate": 2.5}'

Reply and mention

curl -X POST https://api.tickably.com/v1/projects/42/tickets/184/replies \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $TICKABLY_API_KEY" \
  -H "X-API-Secret: $TICKABLY_API_SECRET" \
  -d '{
    "text": "@Sandra Plakke Can you check this?",
    "mentioned_user_ids": [17]
  }'

Use project member IDs from the project details response. Mentioned members receive the same email notification as mentions created in Tickably.

Endpoints

OpenAPI 3.1
GET /me

Current API user

GET /organizations

Companies available to current user

GET /organizations/{organizationId}/members

Company members and pending invites

POST /organizations/{organizationId}/invitations

Invite person to company

GET /organizations/{organizationId}/projects

List company projects

POST /organizations/{organizationId}/projects

Create project in company

GET /organizations/{organizationId}/projects/{projectId}

Get company project

PATCH /organizations/{organizationId}/projects/{projectId}

Update or archive project

DELETE /organizations/{organizationId}/projects/{projectId}

Delete project

GET /projects

Accessible active projects

GET /projects/{projectId}

Project details, members and totals

PATCH /projects/{projectId}/settings

Update project settings

GET /projects/{projectId}/members

List project members

POST /projects/{projectId}/members

Add project member

PATCH /projects/{projectId}/members/{userId}

Change project member role

DELETE /projects/{projectId}/members/{userId}

Remove project member

GET /projects/{projectId}/tickets

List and filter tickets

POST /projects/{projectId}/tickets

Create ticket

GET /projects/{projectId}/tickets/{number}

Ticket, replies, todos and history

PATCH /projects/{projectId}/tickets/{number}

Update ticket

DELETE /projects/{projectId}/tickets/{number}

Delete ticket

POST /projects/{projectId}/tickets/{number}/replies

Add reply

PATCH /projects/{projectId}/tickets/{number}/replies/{replyId}

Edit reply

DELETE /projects/{projectId}/tickets/{number}/replies/{replyId}

Delete reply

POST /projects/{projectId}/tickets/{number}/todos

Add todo

PATCH /projects/{projectId}/tickets/{number}/todos/{todoId}

Update todo

DELETE /projects/{projectId}/tickets/{number}/todos/{todoId}

Delete todo

GET /projects/{projectId}/notes

List project notes

POST /projects/{projectId}/notes

Create project note

PATCH /projects/{projectId}/notes/{noteId}

Update project note

DELETE /projects/{projectId}/notes/{noteId}

Delete project note

GET /projects/{projectId}/categories

List categories

GET /projects/{projectId}/statuses

List statuses

POST /projects/{projectId}/statuses

Create status

PATCH /projects/{projectId}/statuses/{status}

Update status

DELETE /projects/{projectId}/statuses/{status}

Delete status

GET /projects/{projectId}/phases

List phases

POST /projects/{projectId}/phases

Create phase

PATCH /projects/{projectId}/phases/{phase}

Update phase

DELETE /projects/{projectId}/phases/{phase}

Delete phase

Write endpoints accept JSON. Admin-only operations return 403 for other roles. Project notes remain unavailable to clients.

Responses

Successful authenticated responses wrap their result in data.

{
  "data": {
    "created": true,
    "ticket": { "ticket_number": 184 }
  }
}

Creates return 201. Reads, updates and deletes return 200.

Errors

{
  "error": "request_error",
  "message": "Ticket not found"
}
400Invalid input 401Missing or invalid credentials 403User lacks permission 404Resource unavailable 409Project archived or conflicting state 500Unexpected server error