Tickets

Tickets API walkthrough

Create, read, comment on, claim, release, and close an owner-scoped ticket through the managed preview API.

This walkthrough exercises the deployed tickets application through its authenticated /v1/tickets/* routes. Those routes are available to onboarded accounts for managed preview and are absent from the generated public allowlist in the V1 route reference, so they are outside the self-service public API contract. It demonstrates the same Rust serde schema → CBOR → route → executor → dataset path described in the tickets architecture overview, using an sk-rg- key and curl.

Prerequisites

  • A Redgold account and sk-rg- API key.
  • curl and jq.

Keep the key out of shell history by placing it in an environment variable:

export REDGOLD_API_KEY=sk-rg-...
export REDGOLD_API=https://api.redgold.ai

Every route below stamps or filters the authenticated caller as owner. Request bodies contain no ownerId field.

1. Create a ticket

create_response=$(curl --fail-with-body --silent --show-error \
  "$REDGOLD_API/v1/tickets/upsert" \
  -H "Authorization: Bearer $REDGOLD_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{
    "title": "Verify the example pipeline",
    "body": "Run the documented request and record the result.",
    "labels": ["docs", "example"],
    "priority": 100
  }')

ticket_id=$(printf '%s' "$create_response" | jq -r '.ticket_id')
printf 'created %s\n' "$ticket_id"

The response uses snake_case:

{
  "ok": true,
  "ticket_id": "tk-...",
  "updated_ts_ms": 1785456000000
}

Creating a ticket without ticketId generates an id. Supplying an existing owned ticketId updates that ticket by appending another event.

2. Read it back

View one ticket. Requests use camelCase:

curl --fail-with-body --silent --show-error \
  "$REDGOLD_API/v1/tickets/view" \
  -H "Authorization: Bearer $REDGOLD_API_KEY" \
  -H "Content-Type: application/json" \
  --data "$(jq -nc --arg id "$ticket_id" '{ticketId: $id}')" | jq

List your tickets and filter by label:

curl --fail-with-body --silent --show-error \
  "$REDGOLD_API/v1/tickets/list" \
  -H "Authorization: Bearer $REDGOLD_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{"label":"docs","limit":20,"offset":0}' | jq

The list response contains tickets and count. Results are newest-update first. Optional filters are state, label, limit, and offset.

3. Add and read a comment

curl --fail-with-body --silent --show-error \
  "$REDGOLD_API/v1/tickets/comment" \
  -H "Authorization: Bearer $REDGOLD_API_KEY" \
  -H "Content-Type: application/json" \
  --data "$(jq -nc --arg id "$ticket_id" \
    '{ticketId: $id, body: "The example returned the expected rows."}')" | jq

Read the ticket's comments:

curl --fail-with-body --silent --show-error \
  "$REDGOLD_API/v1/tickets/comments" \
  -H "Authorization: Bearer $REDGOLD_API_KEY" \
  -H "Content-Type: application/json" \
  --data "$(jq -nc --arg id "$ticket_id" '{ticketId: $id}')" | jq

Comments are owner-scoped. A caller cannot use a ticket id to enumerate another account's ticket or comments.

4. Claim and release work

A claim records the executor identifier responsible for the ticket. Use a stable identifier from your own automation:

slot_id=docs-example-run

curl --fail-with-body --silent --show-error \
  "$REDGOLD_API/v1/tickets/claim" \
  -H "Authorization: Bearer $REDGOLD_API_KEY" \
  -H "Content-Type: application/json" \
  --data "$(jq -nc --arg id "$ticket_id" --arg slot "$slot_id" \
    '{ticketId: $id, slotId: $slot}')" | jq

Release requires the exact slotId written by the successful claim. This prevents delayed cleanup from clearing a newer assignment:

curl --fail-with-body --silent --show-error \
  "$REDGOLD_API/v1/tickets/release" \
  -H "Authorization: Bearer $REDGOLD_API_KEY" \
  -H "Content-Type: application/json" \
  --data "$(jq -nc --arg id "$ticket_id" --arg slot "$slot_id" \
    '{ticketId: $id, slotId: $slot}')" | jq

5. Close the ticket

curl --fail-with-body --silent --show-error \
  "$REDGOLD_API/v1/tickets/close" \
  -H "Authorization: Bearer $REDGOLD_API_KEY" \
  -H "Content-Type: application/json" \
  --data "$(jq -nc --arg id "$ticket_id" '{ticketId: $id}')" | jq

A final view should report state: "done".

Contract details

PropertyContract
AuthenticationAuthorization: Bearer sk-rg-...
RequestsJSON with camelCase fields such as ticketId and slotId
ResponsesJSON with snake_case fields such as ticket_id and updated_ts_ms
OwnershipCaller identity is verified at the edge; reads and writes are owner-scoped
UpdatesEvent-sourced; the latest event for a ticket id is the current view
Statesopen, in_progress, blocked, done, cancelled

Pipeline implementation can move through staged rollout while this managed-preview HTTP contract remains under review. The routes are not a self-service public API until they appear in the generated V1 route reference.

Troubleshooting

  • 401 means the bearer key is missing, malformed, or revoked.
  • 400 usually means a required camelCase field is absent or a state name is invalid.
  • 404 means the route is unavailable on the selected host.
  • {"error":"ticket not found"} means the ticket is absent or outside the caller's owner scope.
  • A failed release with an assignment mismatch means the ticket is held by a different slotId; read the ticket before retrying.
Copyright © 2026