GET needs two things beyond the credential: the write scope, and an Idempotency-Key.
The key is required, not offered
Moving a card runs Git. A client whose request timed out cannot tell “it failed” from “the answer got lost” — and the only way to find out is to ask again, which is exactly the thing that is not safe to do when asking again might merge a second time. An optional guard against a silent double merge is a guard the one caller who needed it did not use. So it is required on every write, including the ones that touch no repository, because a rule you have to remember when it matters is a rule you will not remember when it matters.header
required
Any string of 16 to 255 characters, from
A-Z a-z 0-9 _ . : -. Make it unique per attempt-you-mean: a run id, a job id, a hash of the thing that caused the write. Not a timestamp you regenerate on retry — that defeats it.What each answer means
1
First time: it runs
The answer is stored under the key.
2
Same key, same request: it replays
You get the first answer back, with
Idempotent-Replay: true, and nothing runs. This is the case the whole mechanism exists for.3
Same key, different request: 409
A key used for two different requests is a bug in your code, and serving the other request’s answer would hide it behind a success.
4
Same key while the first is still running: 409
Wait for it. Running both would be the double merge with extra steps.
A failed attempt releases its key. If a write is rejected for a bad field, fix the field and send it again on the same key — you should not have to invent a new one to correct a typo.
nightly are not the same request.
The credential signs what it does
A write credential is a member of the boards it reaches — it has a user of its own, the same way an agent does. So the card it creates sayscreatedBy: the deploy script, its timeline reads status_changed → the deploy script, and a comment it posts is its own.
That is the point of it. A board whose history says somebody moved a card is a board that cannot answer the only question worth asking after something goes wrong.
What it may do
Two gates, and they answer different questions.403
A credential issued for reading only is told so:
This credential was issued for reading only. Issue one with the write scope.403
Per route, against the role this credential holds on the board in the header:
That needs the member role or higher, and this credential holds viewer on workspace 83729280714017040.Moving a card
The write that runs Git, and the one to read carefully.statusId comes from /v1/board, where each column carries its own id and the minRole it takes to move into it.
Releases
The half most worth automating, because these are the gestures a pipeline has reason to run on a schedule rather than by hand.promote answers with an outcome rather than failing: a release of twelve cards where nine moved and three were refused is news, not an error. The refusals are in the body, each naming its card and the repository that said no.
The rest
What a credential cannot do
Two writes exist in the product and are deliberately not on this API.A proposal waits precisely because a person should look at it, and the provider is what enforces that. A credential that could approve one would be a way to route around the review by writing a script.
Handing out access to a board is the act every other permission rests on. A credential that can grant access is one whose own revocation no longer bounds what it did.