---
title: "Read a job by its handle"
method: GET
path: "/api/v1/jobs/{id}"
tags: ["jobs"]
---

# Read a job by its handle

`GET /api/v1/jobs/{id}`

## Request

- Base URL: `https://app.goosybear.ai`
- URL: `https://app.goosybear.ai/api/v1/jobs/{id}`
- Auth: HTTP bearer

The same read as `POST /api/v1/tools/jobs.read`, by the `job_id` a long-running call answered: its status, when it started and finished, what to read next once it has succeeded, and an error code once it has failed. A handle from another workspace answers `jobs.not_found`, exactly as one that names nothing.

## Path parameters

- `id` string, required

## Query parameters

- `workspace` string

## Response `200`

The call was admitted and dispatched. `ok` says whether the tool succeeded — a refusal the tool itself produced is still a 200, exactly as it is a successful JSON-RPC result over MCP.

- union
  - object: The tool ran and answered.
    - `ok` true, required
    - `job_id` string, required
    - `status` 'queued' | 'running' | 'succeeded' | 'failed', required: queued — accepted, not started; running — under way; succeeded — done, read `result`; failed — it stopped, see error_code.
    - `created_at` string, required: When the job was asked for (ISO 8601).
    - `started_at` string, nullable, required: When it started running, or null before it has.
    - `completed_at` string, nullable, required: When it finished, or null while it has not.
    - `result` object, nullable, required: Once succeeded: what to read next — the clip made, the video the run wrote, or the brand kit fact the confirm confirmed (read it with brand_kit.read). Null until then.
      - `type` 'clip' | 'video' | 'brand_fact', required
      - `id` string, required
    - `error_code` string, nullable, required: Once failed: a stable code for why. Null otherwise.
    - `workspace` string, required: The slug of the workspace this call ran in.
    - `working_in` object, required: Which workspace this call ran in, and how that was decided. Present on every workspace-scoped result.
      - `label` string, required: The chip words — e.g. "working in: Acme Main".
      - `note` string, required: Why this workspace — e.g. "your default", "this call only".
      - `workspace` string, required: The resolved workspace's slug.
      - `source` 'call-override' | 'key-pin' | 'stored-default' | 'sole-reachable', required: Which rung of the R7 precedence resolved the workspace.
  - ToolRefusal: A call that was admitted and dispatched, and did not succeed.
    - `ok` false, required
    - `code` string, required: The typed reason — e.g. `workspace_ambiguous`, `invalid_arguments`, or the tool's own failure code.
    - `message` string, required: A sentence a person can act on.
    - `workspaces` string[]: On a workspace refusal: the slugs this key may pass as `workspace`.
    - `issues` object[]: On `invalid_arguments`: which fields failed, and why.
      - `path` string, required
      - `message` string, required
    - `path` string: On an authoring refusal: where in your call's input it points, e.g. `steps.<key>.params.<field>`.
    - `fix` string: On an authoring refusal: the change to your call that would pass.
    - `instruction` string: On an authoring refusal: what to do next with it.

## Other responses

- `400`: The request could not be used: the body is present but not a JSON object (`tenant_api.malformed_body`); it is a top-level array carrying more messages than this endpoint accepts (`tenant_mcp.batch_too_large`); or the `Idempotency-Key` header is malformed (`tenant_api.idempotency_key_invalid`), disagrees with the body's `idempotency_key` (`tenant_api.idempotency_key_conflict`), or was sent to an action that cannot replay a retry (`tenant_api.idempotency_unsupported`). Nothing ran.
- `401`: No bearer credential, or one that did not resolve. Deliberately ONE undifferentiated answer for absent / unknown / revoked / expired, so the endpoint is never an oracle over the key space.
- `403`: The credential is good but the surface is not open to it — the platform or account API switch is off, or the holder lacks the `api.access` capability. The `code` says which.
- `404`: No such tool. The body names no tool and is identical for every unrecognised name.
- `429`: Over this key's per-minute cap. Carries `Retry-After` and `error.retry_after_seconds`.

---

[API](https://skmtc.dev/goosybear/apis/goosy-bear-api.md) · [All operations](https://skmtc.dev/goosybear/apis/goosy-bear-api/llms.txt) · [OpenAPI document](https://skmtc.dev/goosybear/apis/goosy-bear-api/revisions/6d82fb124064?raw)
