Very Simple Projects

Tickets API

One token. One project. File, report, never delete.

A token opens exactly one project. There is no project parameter. Tickets are numbered 1, 2, 3, the way the person says it. You file, you write in the thread, you change status. You never delete.

Base URL: https://verysimpleprojects.com/api/v1. Auth: Authorization: Bearer TOKEN. Short copy: /llms.txt.

Quickstart

  1. If you have a client_id, open the authorize URL. The person signs in and picks the project. You swap the code for a token.
  2. If you do not, they mint a token in that project's Connect list and paste it.
  3. Call GET /api/v1/me. You get the project, the labels you may use, and the six statuses.
  4. List open tickets before you file a new one. One ticket per problem. Never delete.
curl https://verysimpleprojects.com/api/v1/me \
  -H "Authorization: Bearer TOKEN"

Authentication

Bearer token, scoped to one project. The person revokes it in that project's settings. Tokens do not expire on their own.

Authorization: Bearer TOKEN

Reads always work. New tickets, comments, and title/body edits need an active subscription (402 otherwise). Status, star, and labels still work if the plan has lapsed, so a ticket can always be closed.

How to behave

Statuses

Six, fixed: new, in_progress, blocked, done, deployed, cancelled. Open is the first three. Any status may follow any other. A status change with a note is written into the thread.

GET /me

Connect check: the project, your token's name, labels, statuses.

GET https://verysimpleprojects.com/api/v1/me
Authorization: Bearer TOKEN
{
  "project": { "id": "…", "name": "Agent Heim", "color": "#F2724B" },
  "token": { "name": "Agent Heim · Agnes" },
  "labels": [{ "id": "…", "name": "bug", "color": "#8A8178" }],
  "statuses": ["new", "in_progress", "blocked", "done", "deployed", "cancelled"],
  "open": ["new", "in_progress", "blocked"]
}

DELETE /me

Revoke this token. Call it before you store a new one on reconnect.

DELETE https://verysimpleprojects.com/api/v1/me
Authorization: Bearer TOKEN
{ "ok": true }

GET /labels

Labels the person has made. You cannot add one from here.

GET https://verysimpleprojects.com/api/v1/labels
Authorization: Bearer TOKEN

GET /tickets

Query status=open|closed|all|<status> (default open), optional label=name. Starred first, then newest activity.

GET https://verysimpleprojects.com/api/v1/tickets?status=open
Authorization: Bearer TOKEN
{
  "tickets": [
    {
      "id": "…",
      "number": 12,
      "title": "Login sheet stays open",
      "preview": "First line of the body",
      "status": "in_progress",
      "important": false,
      "labels": [{ "id": "…", "name": "bug", "color": "#8A8178" }],
      "commentCount": 3,
      "updatedAt": "2026-09-11T12:00:00.000Z",
      "closedAt": null
    }
  ]
}

GET /tickets/:number

One ticket by number, with body and comment thread.

GET https://verysimpleprojects.com/api/v1/tickets/12
Authorization: Bearer TOKEN

POST /tickets

File a ticket. title required. labels is a list of existing names. Needs an active subscription.

POST https://verysimpleprojects.com/api/v1/tickets
Authorization: Bearer TOKEN
Content-Type: application/json

{ "title": "Login sheet stays open", "body": "## Steps\n1. Tap Continue with Apple", "labels": ["bug"] }

Returns the full ticket with its new number, 201.

PATCH /tickets/:number

Update title, body, status, note, labels, important. blocked requires note. Title and body edits need a subscription; status, star and labels do not.

PATCH https://verysimpleprojects.com/api/v1/tickets/12
Authorization: Bearer TOKEN
Content-Type: application/json

{ "status": "blocked", "note": "Needs a TestFlight build." }

Comments

GET /tickets/:number/comments lists the thread, oldest first. POST /tickets/:number/comments with { "body" } adds a follow-up. Needs a subscription. A PATCH with note (and no status change) is the same as posting a comment.

POST https://verysimpleprojects.com/api/v1/tickets/12/comments
Authorization: Bearer TOKEN
Content-Type: application/json

{ "body": "Reproduced on iOS 26.1." }

Errors

OAuth 2.0

The person signs in on verysimpleprojects.com and picks the project. Your server swaps the code for a project token. Discovery: /.well-known/oauth-authorization-server.

GET https://verysimpleprojects.com/oauth/authorize
  ?client_id=…
  &redirect_uri=…
  &response_type=code
  &state=…
  &code_challenge=…
  &code_challenge_method=S256

POST https://verysimpleprojects.com/oauth/token
  grant_type=authorization_code
  code=…
  redirect_uri=…
  client_id=…
  client_secret=…
  code_verifier=…

→ { "access_token": "…", "token_type": "Bearer" }

PKCE S256 is supported. Clients must be registered by us; email verysimple@portfoliobox.net. Agent Heim is already registered.