API Documentation

Integrate Artala into your workflows. Manage boards, tasks, comments, labels, custom fields, and more.

Authentication

All API requests require an API key. Create one from Settings → API Keys in your workspace.

Pass your key as a Bearer token in the Authorization header:

Authorization: Bearer tb_your_api_key_here

API keys inherit the role of the user who created them. An Owner's key can do everything; a Member's key is scoped to what that member can access.

API keys begin with tb_. Keep them secret — they grant full access to your workspace data.

Base URL

All endpoints are relative to:

https://app.artala.app/api

Errors

The API uses standard HTTP status codes. Common responses:

CodeMeaning
200Success
201Created
204Success, no content (updates and deletes)
400Bad request — check the request body
401Unauthorized — missing or invalid API key
403Forbidden — your key's role doesn't permit this action
404Not found
429Rate limited — slow down

Rate limits

API requests are rate-limited per key. If you hit the limit, you'll receive a 429 response. Wait and retry.

Boards

List boards

GET /api/boards

Returns all boards in the workspace.

Example response
[
  {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "name": "Engineering Sprint",
    "description": "Backend team tasks",
    "createdAt": "2026-01-15T10:30:00Z",
    "isPrivate": false
  }
]

Get board

GET /api/boards/{boardId}

Returns a single board with its statuses, members, labels, and custom fields.

Create board

POST /api/boards

Creates a new board. Requires Owner or Admin role.

FieldTypeDescription
namestringBoard name (required)
descriptionstring?Optional description
isPrivateboolDefault: false
defaultMemberRolestringDefault: "Member"
sprintsEnabledboolDefault: false
Example request
curl -X POST https://app.artala.app/api/boards \
  -H "Authorization: Bearer tb_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Q3 Roadmap",
    "description": "Product roadmap for Q3 2026",
    "isPrivate": false,
    "sprintsEnabled": true
  }'
Example response (201)
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "name": "Q3 Roadmap",
  "description": "Product roadmap for Q3 2026",
  "createdAt": "2026-05-28T14:22:00Z",
  "isPrivate": false
}

Update board

PUT /api/boards/{boardId}

Updates a board's name, description, or privacy. Requires Owner or Admin role.

Delete board

DELETE /api/boards/{boardId}

Archives a board. Requires Owner or Admin role.

Tasks

Get task

GET /api/tasks/{taskId}

Returns a single task with all its details.

Create task

POST /api/tasks

Creates a new task on a board.

FieldTypeDescription
boardIdguidBoard to create the task on (required)
titlestringTask title (required)
descriptionstring?Markdown description
assigneeIdguid?User ID to assign
priorityint0=Critical, 1=High, 2=Medium (default), 3=Low, 4=None
dueDatedatetime?Due date (UTC)
startDatedatetime?Start date (UTC)
effortint?Story points / effort estimate
statusstring?Status name; null uses workspace default
externalIdstring?Your external reference ID
externalSourcestring?Source system name (e.g. "jira", "github")
checklistItemsstring[]Checklist items to add
Example request
curl -X POST https://app.artala.app/api/tasks \
  -H "Authorization: Bearer tb_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "boardId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "title": "Implement login flow",
    "description": "OAuth2 + TOTP support",
    "priority": 1,
    "dueDate": "2026-06-15T00:00:00Z",
    "effort": 5,
    "checklistItems": [
      "Design login page",
      "Implement OAuth2",
      "Add TOTP verification"
    ]
  }'

Update task

PUT /api/tasks/{taskId}

Updates a task's title, description, assignee, priority, dates, or effort.

FieldTypeDescription
titlestringTask title
descriptionstring?Markdown description
assigneeIdguid?Assignee user ID (null to unassign)
priorityint0–4
dueDatedatetime?Due date (UTC)
startDatedatetime?Start date (UTC)
coverColorstring?Card cover color hex
effortint?Story points

Update status

PATCH /api/tasks/{taskId}/status

Changes a task's status (e.g. "To Do" → "In Progress" → "Done").

curl -X PATCH https://app.artala.app/api/tasks/{taskId}/status \
  -H "Authorization: Bearer tb_your_key" \
  -H "Content-Type: application/json" \
  -d '{ "newStatus": "Done" }'

Delete task

DELETE /api/tasks/{taskId}

Permanently deletes a task and its checklist items, comments, and time entries.

Move to board

POST /api/tasks/{taskId}/move-to-board

Moves a task to a different board.

{ "targetBoardId": "guid", "moveToBacklog": false }

Checklists

Get checklist items

GET /api/tasks/{taskId}/checklist

Returns all checklist items for a task.

Add checklist item

POST /api/tasks/{taskId}/checklist/items

Adds a new checklist item to a task.

{ "title": "Review PR" }

Update checklist item

PATCH /api/tasks/{taskId}/checklist/items/{itemId}

Updates a checklist item's title or completion status.

{ "title": "Review PR", "isComplete": true }

Delete checklist item

DELETE /api/tasks/{taskId}/checklist/items/{itemId}

Deletes a checklist item.

Dependencies

Get dependencies

GET /api/tasks/{taskId}/dependencies

Returns all blocking and blocked-by relationships for a task.

Add dependency

POST /api/tasks/{taskId}/dependencies/{blockingTaskId}

Makes {taskId} blocked by {blockingTaskId}. The blocking task must be completed before the blocked task can proceed.

Remove dependency

DELETE /api/tasks/{taskId}/dependencies/{blockingTaskId}

Removes a blocking relationship.

Labels

List labels

GET /api/labels

Returns all labels defined in the workspace.

Example response
[
  {
    "id": "a1b2c3d4-...",
    "name": "Bug",
    "color": "#f44336",
    "sortOrder": 0
  }
]

Create or update label

POST /api/labels

Creates a new label, or updates an existing one if id is provided. Requires Owner or Admin role.

FieldTypeDescription
idguid?Label ID to update; omit to create
namestringLabel name (required)
colorstringHex colour (default: #9E9E9E)
sortOrderintDisplay order

Delete label

DELETE /api/labels/{labelId}

Deletes a label. Requires Owner or Admin role. Existing task associations are removed.

Get task labels

GET /api/labels/task/{taskId}

Returns labels currently assigned to a task.

Set task labels

PUT /api/labels/task/{taskId}

Replaces all labels on a task with the provided set. Pass an empty array to clear labels.

curl -X PUT https://app.artala.app/api/labels/task/{taskId} \
  -H "Authorization: Bearer tb_your_key" \
  -H "Content-Type: application/json" \
  -d '{ "labelIds": ["a1b2c3d4-...", "e5f6a7b8-..."] }'

Comments

Get comments

GET /api/comments/task/{taskId}

Returns all comments on a task, with replies nested under their parent.

Example response
[
  {
    "id": "b2c3d4e5-...",
    "taskId": "a1b2c3d4-...",
    "authorId": "c3d4e5f6-...",
    "authorName": "Sarah Chen",
    "content": "Looks good, merging now.",
    "isEdited": false,
    "createdAt": "2026-05-28T14:30:00Z",
    "replies": []
  }
]

Add comment

POST /api/comments

Adds a comment to a task. Include parentCommentId to post a reply. Markdown is supported.

FieldTypeDescription
taskIdguidTask to comment on (required)
contentstringComment body, max 4000 chars (required)
parentCommentIdguid?Parent comment ID for replies
Example request
curl -X POST https://app.artala.app/api/comments \
  -H "Authorization: Bearer tb_your_key" \
  -H "Content-Type: application/json" \
  -d '{ "taskId": "a1b2c3d4-...", "content": "Deployment verified." }'

Edit comment

PUT /api/comments/{commentId}

Edits a comment's content. Members and Commenters can edit their own comments within 24 hours; Admins and Owners can edit any comment.

{ "content": "Updated comment text" }

Delete comment

DELETE /api/comments/{commentId}

Deletes a comment and its replies. Members and Commenters can delete their own within 24 hours; Admins and Owners can delete any comment.

Custom fields

Custom fields let you add structured metadata to tasks. Field definitions are per-workspace; values are per-task. Requires the Custom Fields feature to be enabled on your plan.

List fields

GET /api/fields

Returns all custom field definitions for the workspace. Use the field id when setting values on tasks.

Example response
[
  {
    "id": "d4e5f6a7-...",
    "name": "Environment",
    "fieldType": "Choice",
    "choiceOptions": "[\"Staging\",\"Production\",\"Development\"]",
    "isRequired": false,
    "sortOrder": 0
  }
]
Field types: Bool, Text, Number, Choice, Date. Choice options are stored as a JSON array string.

Get task field values

GET /api/fields/task/{taskId}

Returns custom field values set on a task, including the field definition details.

Example response
[
  {
    "fieldId": "d4e5f6a7-...",
    "name": "Environment",
    "fieldType": "Choice",
    "choiceOptions": "[\"Staging\",\"Production\",\"Development\"]",
    "isRequired": false,
    "value": "Production"
  }
]

Set field value

POST /api/fields/task/{taskId}

Sets or updates a single custom field value on a task. Send one request per field.

FieldTypeDescription
fieldIdguidCustom field ID from GET /api/fields (required)
valuestring?Value as string; null to clear. Booleans as "true"/"false", dates as ISO 8601.
Example request
curl -X POST https://app.artala.app/api/fields/task/{taskId} \
  -H "Authorization: Bearer tb_your_key" \
  -H "Content-Type: application/json" \
  -d '{ "fieldId": "d4e5f6a7-...", "value": "Production" }'

Statuses

List statuses

GET /api/statuses

Returns all valid task statuses for the workspace. Use these names when creating or updating tasks. Workspaces can use built-in statuses (To Do, In Progress, Done) or define custom statuses.

Example response
[
  {
    "id": "e5f6a7b8-...",
    "name": "To Do",
    "color": "#9E9E9E",
    "isDefault": true,
    "isDone": false,
    "sortOrder": 0
  }
]

Team

List members

GET /api/team

Returns all members in the workspace. Use the member id as assigneeId when creating or updating tasks.

Example response
[
  {
    "id": "c3d4e5f6-...",
    "fullName": "Sarah Chen",
    "email": "sarah@example.com",
    "role": "Admin",
    "isActive": true
  }
]

Timesheets

Log time

POST /api/timesheets

Logs time against a task. Owner/Admin keys can log time for any user by specifying targetUserId.

FieldTypeDescription
taskIdguidTask to log time against (required)
targetUserIdguid?User to log for; null = the key's user
loggedDatedateDate to log (e.g. "2026-05-28")
hoursdecimalHours worked (0.25 increments)
notestring?Optional note
Example request
curl -X POST https://app.artala.app/api/timesheets \
  -H "Authorization: Bearer tb_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "taskId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "loggedDate": "2026-05-28",
    "hours": 2.5,
    "note": "Backend implementation"
  }'

Timesheet approvals

These endpoints are available when timesheet approvals are enabled for the workspace. Approving, rejecting, and reopening require the caller to be an approver (an explicit assignee, or an Owner/Admin in the unrouted pool). All paths are relative to /api/timesheets.

POST /api/timesheets/week/submit

Submits a week for review. The week is identified by any date inside it. Owner/Admin keys can submit on behalf of another user with targetUserId. Returns the week with its new status and total hours.

FieldTypeDescription
dateInWeekdateAny date within the week to submit (e.g. "2026-06-15")
targetUserIdguid?User whose week to submit; null = the key's user
Example request
curl -X POST https://app.artala.app/api/timesheets/week/submit \
  -H "Authorization: Bearer tb_your_key" \
  -H "Content-Type: application/json" \
  -d '{ "dateInWeek": "2026-06-15" }'
GET /api/timesheets/week/status

Returns the status of a single week. Query parameters: dateInWeek (any date in the week; defaults to the current week) and optional targetUserId.

GET /api/timesheets/my-weeks

Lists the caller's own week statuses over a range. Optional from and to query parameters (default: the last 8 weeks).

GET /api/timesheets/approvals/queue

Returns the submitted weeks awaiting the caller's review — weeks routed to them plus, for Owners/Admins, the unrouted pool. Each row includes the owner, week dates, and total hours.

GET /api/timesheets/approvals/decided

Returns recently approved and rejected weeks the caller can reopen or correct.

POST /api/timesheets/weeks/{weekId}/approve

Approves a submitted week. The week becomes locked. Fires timesheet.week.approved.

POST /api/timesheets/weeks/{weekId}/reject

Rejects a submitted week with a note explaining what needs to change. The member can edit and resubmit. Fires timesheet.week.rejected.

FieldTypeDescription
notestringReason shown to the member
Example request
curl -X POST https://app.artala.app/api/timesheets/weeks/3fa85f64-5717-4562-b3fc-2c963f66afa6/reject \
  -H "Authorization: Bearer tb_your_key" \
  -H "Content-Type: application/json" \
  -d '{ "note": "Please move the Friday hours to the correct task." }'
POST /api/timesheets/weeks/{weekId}/reopen

Reopens an approved week back to draft (subject to separation-of-duties rules). Fires timesheet.week.reopened.

POST /api/timesheets/weeks/{weekId}/unsubmit

Retracts a still-pending submitted week back to draft so it can be edited again.

PUT /api/timesheets/settings/approvals

Enables or disables the approval workflow for the workspace (Owner/Admin). Enabling records a grandfather date so earlier weeks aren't pulled in.

FieldTypeDescription
enabledboolTurn approvals on or off
PUT /api/timesheets/settings/week-start-day

Sets the day each approval week begins (Owner/Admin). A change takes effect from a future boundary so existing weeks are not re-sliced.

FieldTypeDescription
weekStartDayint0 = Sunday … 6 = Saturday

OData feeds

Artala exposes read-only OData v4 feeds that you can query directly from Excel, Power BI, Tableau, Google Sheets, or any OData-compatible tool. OData feeds support filtering, sorting, pagination, field selection, and aggregation.

Authentication

OData feeds use the same API key as the REST API. Pass it as a Bearer token:

curl "https://app.artala.app/odata/Tasks?\$filter=IsOverdue eq true" \
  -H "Authorization: Bearer tb_your_key"

Base URL

https://app.artala.app/odata/{FeedName}

Query options

OptionExampleDescription
$filterIsOverdue eq trueFilter rows
$orderbyDueDate descSort results
$selectTitle,Status,DueDateChoose specific columns
$top10Limit number of results
$skip20Paginate results
$counttrueInclude total count
$applygroupby((...),aggregate(...))Aggregation and grouping

Available feeds

GET /odata/Tasks

All active tasks across all boards.

Columns: Id, BoardId, BoardName, Title, Description, Status, Priority, PriorityName, AssigneeId, AssigneeName, DueDate, IsOverdue, IsBacklog, IsArchived, CompletedAt, CreatedAt, UpdatedAt, Effort, ExternalId, ExternalSource, and more.

Example queries
# High priority overdue tasks
/odata/Tasks?$filter=IsOverdue eq true and Priority eq 3&$orderby=DueDate

# Completed this month
/odata/Tasks?$filter=CompletedAt ge 2026-05-01T00:00:00Z&$orderby=CompletedAt desc

# Tasks with effort estimates
/odata/Tasks?$filter=Effort ne null&$orderby=Effort desc
GET /odata/BacklogTasks

Tasks from the global backlog (Idea / Planned / Ready).

# Ready for sprint
/odata/BacklogTasks?$filter=Status eq 'Ready'&$orderby=Priority desc,SortOrder
GET /odata/Boards

Board list with task and member counts.

Columns: Id, Name, Description, IsPublic, IsBacklogBoard, TaskCount, MemberCount, CreatedAt, UpdatedAt.

GET /odata/Members

Workspace user list with roles.

Columns: Id, FullName, Email, Role, IsActive, TotpEnabled, LastLoginAt, CreatedAt.

# Active members without 2FA
/odata/Members?$filter=IsActive eq true and TotpEnabled eq false&$select=FullName,Email,Role
GET /odata/Sprints

Sprint list with task counts and effort totals.

Columns: Id, BoardId, BoardName, Name, Goal, StartDate, EndDate, Status, TotalTasks, CompletedTasks, TotalEffort, CompletedEffort, CompletedAt, CreatedAt.

# Velocity by sprint
/odata/Sprints?$filter=Status eq 'Completed'&$select=Name,BoardName,TotalEffort,CompletedEffort&$orderby=StartDate
GET /odata/SprintTasks

One row per task-sprint pair. Use for sprint-level reporting and burndown analysis.

# Incomplete tasks in active sprints
/odata/SprintTasks?$filter=SprintStatus eq 'Active' and CompletedAt eq null
GET /odata/TaskHistory

Full audit trail of task field changes. Use for cycle time, lead time, and flow analysis.

Columns: Id, TaskId, TaskTitle, BoardId, BoardName, FieldChanged, OldValue, NewValue, ChangedById, ChangedBy, ChangedAt.

# Status changes only
/odata/TaskHistory?$filter=FieldChanged eq 'Status'&$orderby=ChangedAt desc
GET /odata/TaskLabels

One row per label per task. Use for grouping and filtering by label.

Columns: TaskId, TaskTitle, BoardId, BoardName, LabelName, Color.

GET /odata/TaskFieldValues

Custom field values — one row per field per task.

Columns: TaskId, TaskTitle, FieldId, FieldName, FieldType, Value.

GET /odata/TaskBlockers

Blocking relationships between tasks. BlockedTask is waiting on BlockingTask to finish.

# Active blockers
/odata/TaskBlockers?$filter=BlockingTaskIsDone eq false&$orderby=BlockedTaskTitle
GET /odata/TimeEntries

Time entries — one row per entry. Available when time tracking is enabled.

Columns: Id, TaskId, TaskTitle, BoardId, BoardName, UserId, UserName, LoggedDate, Hours, Note, WeekStatus, CreatedAt. WeekStatus is the approval status of the entry's timesheet week (Draft, Submitted, Approved, or Rejected) when approvals are enabled, otherwise null — filter on it to report only approved time.

# Total hours per task
/odata/TimeEntries?$apply=groupby((TaskId,TaskTitle),aggregate(Hours with sum as TotalHours))

# Approved hours only (for payroll)
/odata/TimeEntries?$filter=WeekStatus eq 'Approved'
GET /odata/TimesheetWeeks

Timesheet approval weeks — one row per submitted, approved, or rejected week. Available when timesheets are enabled; Owners/Admins see all weeks, other users see only their own.

Columns: Id, UserId, UserName, WeekStartDate, WeekEndDate, WeekStartDay, Status, TotalHours, SubmittedAt, ApproverId, ApproverName, ActionedByUserId, ActionedByName, ActionedAt, RejectNote, CreatedAt.

# Weeks awaiting approval
/odata/TimesheetWeeks?$filter=Status eq 'Submitted'

# Approved hours per person this quarter
/odata/TimesheetWeeks?$apply=filter(Status eq 'Approved')/groupby((UserName),aggregate(TotalHours with sum as Hours))
OData feeds are read-only. To create or update data, use the REST API endpoints above. For live dashboards, connect Power BI or Excel directly to the OData URL with your API key.

Webhooks

Configure webhooks in Settings → Webhooks to receive real-time notifications when events happen in your workspace. Artala sends a POST request to your URL with a JSON payload.

Available events

EventFires when
Boards
board.createdA board is created
board.updatedA board is renamed or updated
board.archivedA board is archived
board.unarchivedA board is restored from archive
board.member.addedA member is added to a board
board.member.removedA member is removed from a board
Tasks
task.createdA task is created
task.updatedA task's fields are updated
task.completedA task is moved to a "done" status
task.assignedA task is assigned or reassigned
task.due_date_changedA task's due date is changed
task.deletedA task is deleted
task.archivedA task is archived
task.unarchivedA task is restored from archive
task.backlog.addedA task is moved to the backlog
task.backlog.removedA task is moved out of the backlog
task.movedA task is moved to another board
task.moved_to_backlogA task is moved to another board's backlog
task.bulk_importedTasks are bulk-imported into a board
Sprints
sprint.startedA sprint is started
sprint.completedA sprint is completed
task.sprint.addedA task is added to a sprint
task.sprint.removedA task is removed from a sprint
task.sprint.movedA task is moved between sprints
Comments
comment.createdA comment is added to a task
comment.updatedA comment is edited
comment.deletedA comment is deleted
Attachments
attachment.addedA file is attached to a task
attachment.deletedAn attachment is removed
Members
member.invitedA member is invited to the workspace
member.role_changedA member's role is changed
member.deactivatedA member is deactivated
Timesheet approvals
timesheet.week.submittedA member submits a timesheet week for review
timesheet.week.approvedAn approver approves a submitted week
timesheet.week.rejectedAn approver rejects a week (payload includes the note)
timesheet.week.reopenedAn approved week is reopened back to draft
Timesheet approval events fire only when timesheet approvals are enabled for the workspace. Each webhook delivery includes an X-Artala-Event header with the event name and an X-Artala-Delivery header with a unique delivery ID.

List webhooks

GET /api/webhooks

Returns all webhooks configured in the workspace.

Create webhook

POST /api/webhooks

Creates a new webhook, or updates an existing one if id is provided. Requires Owner or Admin role.

FieldTypeDescription
idguid?Webhook ID to update; omit to create
namestringWebhook name (required)
urlstringDelivery URL, must be https or http (required)
secretstringHMAC signing secret, min 8 chars (required)
eventsstringComma-separated event names (required)
isActiveboolDefault: true
Example request
curl -X POST https://app.artala.app/api/webhooks \
  -H "Authorization: Bearer tb_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Slack notifications",
    "url": "https://hooks.example.com/artala",
    "secret": "my-signing-secret",
    "events": "task.created,task.completed"
  }'

Delete webhook

DELETE /api/webhooks/{webhookId}

Deletes a webhook. Requires Owner or Admin role.