Rotate a bound endpoint's label

Issues a fresh §9.3(b) label for the binding identified by {id} (the binding_id from the bind response). The prior label is invalidated immediately — a subsequent profile GET on the old label returns 404. Only endpoint_id_label is returned; the connect_secret is not rotated (it stays fixed per binding).

Rotate on your window cadence to keep the bound-resolver label short-lived. Because rotation is atomic and the old label dies instantly, poll the new label before discarding the old one only if you cannot tolerate a single missed cycle.

Worked example

ts
import { signRequest } from "@openchildsafety/ocss"
 
const BASE  = "https://phosra-api-sandbox-production.up.railway.app/api/v1"
const seed  = new Uint8Array(Buffer.from(process.env.OCSS_SANDBOX_TEST_SEED_B64URL!, "base64url"))
const keyID = process.env.OCSS_SANDBOX_KEY_ID!
 
const bindingId = "c8ff82dd-4aa8-4a52-a235-ae13717eb4c8" // from the bind response
const targetURI = `${BASE}/enforcement-endpoints/${bindingId}/rotate`
const headers = signRequest({ method: "POST", targetURI, body: new TextEncoder().encode("{}"), keyID, seed, created: Math.floor(Date.now() / 1000) })
headers["Content-Type"] = "application/json"
 
const res = await fetch(targetURI, { method: "POST", headers, body: "{}" })
console.log(res.status, await res.json())

The sign_request / SignRequest helper is defined once in the request-signing guide — its Python, Go, and curl+openssl recipes are verified against this sandbox. Even an empty-body POST covers content-digest (over the bytes {}).

Example synthetic sandbox 200 response (credential redacted):

json
{
  "endpoint_id_label": "REDACTED_SANDBOX_ENDPOINT_ID_LABEL"
}

The prior label (iGrFqzp4…) now returns 404 on GET /enforcement-profiles/{endpoint_id}.