pino logs for Sume API calls: job_id, request_id, redacted keys
Log every Sume call with pino child loggers that carry job_id and the error request_id, and redact the Authorization header so keys never reach the log store.

Create one pino logger with redact set for the Authorization header and your signing secret, then bind a child logger to each job with log.child({ job_id }). Every line from that job's submit, polls and webhook now carries the same job_id, and a failed call also logs the request_id from Sume's error envelope. A support ticket then needs one string, not a time window.
The id to join on is the job id. It is what Jobs and results tells you to store from the submit response, and it is the job_id on the webhook, so submit logs, poll logs and webhook logs line up without a lookup table.
A logger that cannot leak the key
The helper below submits a video job, logs the outcome and returns the id. Note what it does not log: the Authorization header, the request body with the prompt if you treat prompts as sensitive, and the signing secret.
import pino from "pino";
const log = pino({
redact: { paths: ["headers.authorization", "secret", "*.secret"], censor: "[redacted]" },
});
const key = process.env.SUME_API_KEY;
if (!key) throw new Error("SUME_API_KEY is empty");
export async function submit(prompt, idempotencyKey) {
const l = log.child({ idempotency_key: idempotencyKey });
const res = await fetch("https://api.sume.com/v1/videos", {
method: "POST",
headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json", "Idempotency-Key": idempotencyKey },
body: JSON.stringify({ model: "sume/auto", prompt, duration: 5 }),
});
const body = await res.json();
if (!res.ok) {
l.error({ http_status: res.status, code: body.error?.code, request_id: body.error?.request_id }, "submit failed");
throw new Error(body.error?.code ?? "submit_failed");
}
l.child({ job_id: body.id }).info({ status: body.status }, "job accepted");
return body.id;
}Which fields to log
Keep the set small and join on ids. Fields with unbounded values, such as prompts, belong in your own data store, not in every log line.
| Field | Where it comes from | Why |
|---|---|---|
| job_id | Submit response id, webhook job_id | Primary join key across submit, polls and webhooks |
| idempotency_key | Your own header value | Shows whether a retry reused the key |
| http_status and error.code | Submit or poll response | 429 queue_full and rate_limited need different handling |
| error.request_id | Error envelope | What Sume support can look up for a failed call |
| status or event | Poll status, webhook event | job.completed, job.failed or job.canceled |
Caveats
- Redaction paths match object structure, not strings. Log request headers under a
headerskey, or add the path you actually use. - Never log the signing secret or compare values in the failure path of a webhook check. Each delivery carries an
x-sume-webhook-secret-fingerprintheader, so you can compare secrets without printing them. - A log line is not a recovery plan. Keep the id in durable storage, because a restarted process needs it to resume polling instead of submitting again.
Sources
Related posts
More in Developers
- 1080x1350 sent as aspect_ratio: what Ideogram, Grok, Imagen get
Send pixels instead of a ratio and Sume snaps to the nearest native ratio. Tested table for 1080x1350, 1200x628 and 1500x500 across four model families.
- Poll 40 Sume jobs without bursts: jitter, retry-after, next poll hint
Watch many Sume jobs in asyncio: stagger the first poll, sleep next_poll_after_seconds with jitter, and back off on a 429 retry-after from the status route.
- Poll Sume audio jobs at the recommended interval, not a fixed sleep
The Sume job status response tells you when to poll next and whether the job is terminal. Read those fields instead of hardcoding sleep(2).
- Ported Sora wrapper blocked until done? Sume sync stops at 30 s
A wrapper that blocks until the video is done will time out on Sume sync mode, which waits at most 30 seconds. Return the job id and poll, never resubmit.
Written by Sume