Table of Contents

  1. Authentication
  2. Resources
  3. Endpoints
  4. Webhooks

NOTICE: This is the documentation for the legacy REST API. It is being replaced with the GraphQL API.

The todo.sr.ht API allows you to browse, create, and manage repositories on todo.sr.ht programmatically. This API follows the standard sourcehut API conventions.

#Authentication

Authentication is done via the meta.sr.ht OAuth flow. The following OAuth scopes are available for todo.sr.ht:

  • events:read: read ticket events
  • trackers:read, trackers:write: read & write tracker details
  • tickets:read, tickets:write: read & write tickets & comments
#Resources
#Comment resource
{
  "id": integer,
  "created": "timestamp",
  "submitter": { short-form user resource },
  "text": "string (markdown)",
  "ticket" { short-form ticket resoruce }
}

Short form:

{
  "id": integer,
  "created": "timestamp",
  "submitter": { short-form user resource },
  "text": "string (markdown)"
}
#Event resource
{
  "id": integer,
  "created": "timestamp",
  "event_type": [ ...list of event types... ],
  "old_status": status or null,
  "old_resolution": resolution or null,
  "new_status": status or null,
  "new_resolution": resolution or null,
  "user": { short-form user resource } or null,
  "ticket": { short-form ticket resource } or null,
  "comment": { short-form comment resource } or null,
  "label": [ ...list of strings... ] or null,
  "by_user": { short-form user resource } or null,
  "from_ticket": { short-form ticket resource } or null
}

Event type may be one or more of created, comment, status_change, label_added, label_removed, assigned_user, unassigned_user, user_mentioned, or ticket_mentioned.

Status fields may be one of reported, confirmed, in_progress, pending, or resolved.

Resolution fields may be one of unresolved, fixed, implemented, wont_fix, by_design, invalid, duplicate, or not_our_bug.

The by_user and from_ticket features are used for events where a ticket or user was mentioned in a comment somewhere. The ticket field and user field are set to the mentioned ticket or user, and the by_user or from_ticket field are set according to the discussion where the mention occured.

#Label resource
{
  "name": "string",
  "created": "timestamp",
  "colors": {
    "background": "#rrggbb",
    "text": "#rrggbb"
  },
  "tracker": { short-form tracker resource }
}

Short form:

{
  "name": "string",
  "colors": {
    "background": "#rrggbb",
    "text": "#rrggbb"
  }
}
#Ticket resource
{
  "id": integer,
  "ref": "string",
  "tracker": { short-form tracker resource },
  "title": "ticket subject",
  "created": "timestamp",
  "updated": "timestamp",
  "submitter": { short-form user resource },
  "description": "string (markdown)",
  "status": status,
  "resolution": resolution,
  "permissions": {
    "anonymous": [ ...list of strings... ] or null,
    "submitter": [ ...list of strings... ] or null,
    "user": [ ...list of strings... ] or null,
  },
  "labels": [ ...list of label names... ],
  "assignees": [ ...list of short-form user resources... ]
}

Status fields may be one of reported, confirmed, in_progress, pending, or resolved.

Resolution fields may be one of unresolved, fixed, implemented, wont_fix, by_design, invalid, duplicate, or not_our_bug.

Permissions may be one or more of browse, submit, comment, edit, and triage. If null, the permissions are inherited from the tracker.

Short form:

{
  "id": integer,
  "ref": "string",
  "tracker": { short-form tracker resource }
}
#Tracker resource
{
  "owner": { short-form user resource },
  "created": "timestamp",
  "updated": "timestamp",
  "name": "string",
  "description": "string (markdown)",
  "default_permissions": {
    "anonymous": [ ...list of permissions... ],
    "submitter": [ ...list of permissions... ],
    "user": [ ...list of permissions... ]
  }
}

Permissions may be one or more of browse, submit, comment, edit, and triage.

Short form:

{
  "owner": { short-form user resource },
  "created": "timestamp",
  "updated": "timestamp",
  "name": "string",
}
#Endpoints

Note: usernames are prefixed with ~.

#GET /api/user/:username

Retrieves a user resource.

#GET /api/user

Equivalent to /api/user/:username, implies the authenticated user.

#GET /api/user/:username/trackers

List of tracker resources owned by this user.

OAuth scope: trackers:read

#GET /api/trackers

Equivalent to /api/user/:username/trackers, implies the authenticated user.

OAuth scope: trackers:read

#POST /api/trackers

Creates a new tracker resource.

OAuth scope: trackers:write

Request body

{
  "name": "tracker name",
  "description": "tracker description (markdown)" (optional)
}

Response

The new tracker resource

#GET /api/user/:username/trackers/:tracker-name

Retrieves a tracker resource.

OAuth scope: trackers:read

#GET /api/trackers/:tracker-name

Equivalent to /api/user/:username/trackers/:tracker-name, implies the authenticated user.

OAuth scope: trackers:read

#PUT /api/user/:username/trackers/:tracker-name

Updates a tracker resource.

{
  "description": "tracker description (markdown)" (optional)
}

OAuth scope: trackers:write

#PUT /api/trackers/:tracker-name

Equivalent to /api/user/:username/trackers/:tracker-name, implies the authenticated user.

OAuth scope: trackers:write

#DELETE /api/user/:username/trackers/:tracker-name

Deletes a tracker resource.

OAuth scope: trackers:write

#DELETE /api/trackers/:tracker-name

Equivalent to /api/user/:username/trackers/:tracker-name, implies the authenticated user.

OAuth scope: trackers:write

#GET /api/user/:username/trackers/:tracker-name/labels

List of label resources associated with this tracker.

OAuth scope: trackers:read

#GET /api/trackers/:tracker-name/labels

Equivalent to /api/:username/trackers/:tracker-name/labels, implies the authenticated user.

OAuth scope: trackers:read

#GET /api/user/:username/trackers/:tracker-name/tickets

List of ticket resources associated with this tracker.

OAuth scope: tickets:read

#GET /api/trackers/:tracker-name/tickets

Equivalent to /api/user/:username/trackers/:tracker-name/tickets, implies the authenticated user.

OAuth scope: tickets:read

#POST /api/user/:username/trackers/:tracker-name/tickets

Creates a new ticket resources associated with this tracker.

OAuth scope: tickets:write

Request body

{
  "title": "ticket title",
  "description": "ticket description (markdown)" (optional)
}

Response

The new ticket resource

#POST /api/trackers/:tracker-name/tickets

Equivalent to /api/user/:username/trackers/:tracker-name/tickets, implies the authenticated user.

OAuth scope: tickets:write

#GET /api/user/:username/trackers/:tracker-name/tickets/:ticket-id

Retrieves a ticket resource.

OAuth scope: tickets:read

#GET /api/trackers/:tracker-name/tickets/:ticket-id

Equivalent to /api/user/:username/trackers/:tracker-name/tickets/:ticket-id, implies the authenticated user.

OAuth scope: tickets:read

#PUT /api/user/:username/trackers/:tracker-name/tickets/:ticket-id

Updates a ticket resource. This endpoint is used to:

  • Open or close tickets
  • Comment on tickets
  • Add or remove labels

OAuth scope: tickets:write

Request body

{
  "comment": "comment text (markdown)" (optional),
  "status": "ticket status enum" (optional),
  "resolution": "ticket resolution enum" (optional),
  "labels": ["list of desired label names"] (optional)
}

Ticket status enum

One of:

  • reported
  • confirmed
  • in_progress
  • pending
  • resolved

Ticket resolution enum

One of:

  • unresolved
  • fixed
  • implemented
  • wont_fix
  • by_design
  • invalid
  • duplicate
  • not_our_bug

Response

{
  "ticket": { affected ticket resource },
  "events": [
    list of event resources created by this update
  ]
}
#PUT /api/trackers/:tracker-name/tickets/:ticket-id

Equivalent to /api/user/:username/trackers/:tracker-name/tickets/:ticket-id, implies the authenticated user.

OAuth scope: tickets:write

#GET /api/user/:username/trackers/:tracker-name/tickets/:ticket-id/events

List of event resources associated with this ticket.

OAuth scope: tickets:read

#GET /api/trackers/:tracker-name/tickets/:ticket-id/events

Equivalent to /api/user/:username/trackers/:tracker-name/tickets/:ticket-id/events, implies the authenticated user.

OAuth scope: tickets:read

#PUT /api/user/:username/trackers/:tracker-name/tickets/:ticket-id/comments/:comment-id

Edits a comment. Note that the comment ID is required, not the event ID.

Request body

{
  "text": "new comment text (markdown)"
}

OAuth scope: tickets:write

#PUT /api/trackers/:tracker-name/tickets/:ticket-id/comments/:comment-id

Equivalent to /api/user/:username/trackers/:tracker-name/tickets/:ticket-id/comments/:comment-id, implies the authenticated user.

OAuth scope: tickets:write

#Webhooks
#/api/user/...

Webhook for user events. Includes the standard webhook endpoints

#tracker:create

Issued when the user creates a new tracker.

OAuth scope: trackers:read

Request body

The new tracker resource.

#tracker:update

Issued when the user updates a tracker.

OAuth scope: trackers:read

Request body

The affected tracker resource.

#tracker:delete

Issued when the user deletes a tracker.

OAuth scope: trackers:read

Request body

{
  "id": the affected tracker ID
}
#ticket:create

Issued when the user creates a new ticket.

OAuth scope: tickets:read

Request body

The new ticket resource.

#event:create

Issued when a new event is created for a ticket on this tracker.

OAuth scope: tickets:read

Request body

The new event resource.

#/api/user/:username/trackers/:tracker-name

Webhook for tracker events. Includes the standard webhook endpoints

#label:create

Issued when a new label is added to this tracker.

OAuth scope: trackers:read

Request body

The new label resource.

#label:delete

Issued when a label is removed from this tracker.

OAuth scope: trackers:read

Request body

{
  "id": affected label ID
}
#ticket:create

Issued when a ticket is created for this tracker.

OAuth scope: tickets:read

Request body

The new ticket resource.

#/api/user/:username/trackers/:tracker-name/tickets/:ticket-id

Webhook for ticket events. Includes the standard webhook endpoints

#ticket:update

Issued when this tickets details are updated.

OAuth scope: tickets:read

Request body

The updated ticket resource.

#event:create

Issued when a new event is created for this this ticket.

OAuth scope: tickets:read

Request body

The new event resource.

About this wiki

commit 1652e5542bbed7cec2076cb51c73320ab75cc27c
Author: Conrad Hoffmann <ch@bitfehler.net>
Date:   2023-09-14T12:56:57+02:00

staff: fix header level
Clone this wiki
https://git.sr.ht/~sircmpwn/sr.ht-docs (read-only)
git@git.sr.ht:~sircmpwn/sr.ht-docs (read/write)