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.