Browse documentationGetting started

Start here

Make the first request boring

Keep the API origin, credential, and workspace selection explicit. A small request helper makes authentication consistent without hiding status codes or response headers that callers need for errors, pagination, and streaming.

Configure the client

Store keys in a secret manager or local environment file outside source control. Duet accepts a Bearer credential; never place a key in a URL, query string, build artifact, or browser bundle.

export DUET_API_URL="https://ctl.duet.so"
export DUET_API_KEY="duet_sk_replace_with_your_key"
export async function duetRequest(path: `/v1/${string}`, init: RequestInit = {}) {
  const response = await fetch(`${process.env.DUET_API_URL}${path}`, {
    ...init,
    headers: {
      authorization: `Bearer ${process.env.DUET_API_KEY}`,
      ...init.headers,
    },
  })
 
  if (!response.ok) throw new Error(`Duet request failed: ${response.status}`)
  return response
}

Inspect the credential

Start with GET /v1/whoami. It returns the user, workspace memberships, and exact scopes attached to the credential without changing state.

curl --fail-with-body \
  --header "Authorization: Bearer $DUET_API_KEY" \
  "$DUET_API_URL/v1/whoami"

Then open the endpoint reference and select an operation whose required scope is present on the key.

Preserve the response

Do not immediately flatten every response into application-specific data. Status, headers, cursor fields, and event identifiers are part of the protocol and often carry the information needed to recover after a failure.