---
title: "Workflow Run Event"
method: POST
path: "workflow_run.succeeded"
---

# Workflow Run Event

`POST workflow_run.succeeded` (webhook)

Sent when a workflow run finishes, fails or is cancelled.

## Payload

- WorkflowRunWebhookEvent: Delivered when a workflow run reaches a terminal state.
  - `id` string, required: Unique event id, repeated in the webhook-id header.
  - `type` 'inference.completed' | 'inference.failed' | 'inference.cancelled' | 'training.succeeded' | 'training.failed' | 'scoring_run.completed' | 'scoring_run.failed' | 'workflow_run.succeeded' | 'workflow_run.failed' | 'workflow_run.cancelled', required: Every event the public API can deliver. Terminal outcomes only: a job produces exactly one of these, once. The value is what appears as ``type`` in the envelope and as the operation name in the OpenAPI ``webhooks`` block, so it is a public contract.
  - `created_at` string, required: When the event was raised (RFC 3339).
  - `data` GetWorkflowRunOutput, required
    - `run_id` string, uuid, required: Unique identifier for this workflow run.
    - `status` 'pending' | 'running' | 'success' | 'failure' | 'cancelled', required: Enum representing the status of a blueprint run.
    - `poll_interval_seconds` integer, nullable: Suggested polling interval in seconds. Present while PENDING or RUNNING.
    - `steps` GetWorkflowRunStep[]: Status of each step composing the workflow run.
      - `name` string, required: The name of the workflow step
      - `status` 'pending' | 'running' | 'success' | 'failure' | 'cancelled', required: Enum representing the status of a blueprint run.
      - `error` string, nullable: The error details if any
      - `error_code` string, nullable: Machine-readable error code if the step failed.
    - `estimated_price_creative_units` number, nullable: Estimated Creative Units price. Present when available.
    - `completed_at` string, date-time, nullable: Completion timestamp. Present only on SUCCESS.
    - `actual_price_creative_units` number, nullable: Actual Creative Units price charged. Present only on SUCCESS.
    - `outputs` WorkflowRunAsset[], nullable: Generated assets. Present only on SUCCESS.
      - `object_id` string, uuid, required: Unique identifier of the generated object.
      - `object_type` 'directory' | 'file' | 'asset' | 'style' | 'blueprint' | 'skill', required
      - `file_id` string, uuid, nullable: File ID — pass directly as input to forge or workflow runs without re-uploading.
      - `url` string, required: Download URL for the asset.
      - `content_type` string, required: MIME type, e.g. image/png or video/mp4.
      - `preview_url` string, nullable: Image preview URL.
      - `width` integer, nullable: Width in pixels.
      - `height` integer, nullable: Height in pixels.
      - `duration_seconds` number, nullable: Duration in seconds for video assets.
      - `file_size_bytes` integer, nullable: File size in bytes.
      - `metadata` FileMetadataView: What an engine needs beyond the image to build a resource from a file. Each kind is null when absent.
        - `tile` TileMetadataView: Where a game tile's sprite sits on its grid, in the sprite's own pixels from its top-left corner.
          - `shape` 'SQUARE' | 'HEXAGON', required: The outline of one cell of the grid, seen from straight above.
          - `orientation` 'DIAMOND' | 'ALIGNED' | 'POINTY_TOP' | 'FLAT_TOP', required: How a cell's outline is turned to the camera. A square cell is either ``DIAMOND``, turned 45 degrees so its base reads as a diamond (the isometric look), or ``ALIGNED`` with the camera, as top-down maps are. A hexagon has either a vertex (``POINTY_TOP``) or an edge (``FLAT_TOP``) at the top.
          - `elevation` number, required: Camera tilt in degrees above the ground plane; 90 is straight down.
          - `facing` integer, required: Quarter turn of the camera around the tile, in degrees clockwise seen from above: 0, 90, 180, or 270. A hexagon is only drawn facing 0.
          - `footprint_width` integer, required: Cells the footprint covers across (the base's right-hand edge) at facing 0.
          - `footprint_depth` integer, required: Cells the footprint covers deep (the base's left-hand edge) at facing 0.
          - `height` number, required: Wall height in cell sides: 0 is a flat ground tile, 1 a cube on a square.
          - `tile_width` integer, required: Width in pixels of one cell's base outline in the sprite.
          - `tile_height` integer, required: Height in pixels of one cell's base outline in the sprite.
          - `anchor` TilePointView, required
            - `x` number, required: Pixels right of the sprite's left edge.
            - `y` number, required: Pixels down from the sprite's top edge.
          - `cell_center` TilePointView, required
            - `x` number, required: Pixels right of the sprite's left edge.
            - `y` number, required: Pixels down from the sprite's top edge.
          - `base_outline` TilePointView[], required: The footprint's whole base outline, clockwise on screen from the anchor's vertex or edge.
            - `x` number, required: Pixels right of the sprite's left edge.
            - `y` number, required: Pixels down from the sprite's top edge.
          - `subject_id` string, uuid, nullable: What the tile shows. Every facing of one subject shares it, so a tileset can group them.
        - `nine_slice` NineSliceMetadataView: The insets a 9-slice draws a UI element by, in the image's own pixels in from each edge. The corners are drawn at their own size, the edges stretch along their length, and the centre stretches both ways.
          - `left` integer, required: Pixels in from the left edge.
          - `top` integer, required: Pixels in from the top edge.
          - `right` integer, required: Pixels in from the right edge.
          - `bottom` integer, required: Pixels in from the bottom edge.
          - `source` 'DETECTED' | 'USER', required
        - `sprite_sheet` SpriteSheetMetadataView: The frame grid a sprite sheet was packed on, in the sheet's own pixels from its top-left corner. Cells start `margin` pixels in from the sheet's edges with `spacing` pixels between them.
          - `columns` integer, required: Cells across.
          - `rows` integer, required: Cells down.
          - `cell_width` integer, required: Width of one cell in pixels.
          - `cell_height` integer, required: Height of one cell in pixels.
          - `margin` integer, required: Pixels between the sheet's edges and the outer cells.
          - `spacing` integer, required: Pixels between neighbouring cells.
          - `frames` SpriteSheetFrameView[], required: The frames, in play order: left to right, then top to bottom, unless the list orders them otherwise.
            - `index` integer, required: The frame's cell in reading order over the whole grid (left to right, then top to bottom). Cells that hold no frame are left out, so indexes can skip.
            - `x` integer, required: The frame's left edge on the sheet, in pixels.
            - `y` integer, required: The frame's top edge on the sheet, in pixels.
            - `w` integer, required: The frame's width in pixels.
            - `h` integer, required: The frame's height in pixels.
            - `anchor` TilePointView
              - …
          - `animations` SpriteSheetAnimationView[], required: Named animations over the frames. When empty, play the sheet as one animation named `default` over every frame in `frames` order, at 12 fps, looping.
            - `name` string, required: The animation's name.
            - `frames` integer[], required: Frame indexes (`frames[].index`), in play order.
            - `fps` number, required: Frames per second.
            - `loop` boolean, required: Whether the animation restarts after its last frame.
    - `error` string, nullable: Error message. Present only on FAILURE.
    - `error_code` string, nullable: Machine-readable error code. Present only on FAILURE. Balance-related values: `BlueprintInsufficientBalanceError` (the workspace ran out of Creative Units — top up and resubmit), `BlueprintBalanceUnavailableError` (the balance could not be verified, retry later) and `BlueprintUsageLimitExceededError` (the member who started the run is past their usage limit: ask a workspace admin for more, or wait for it to reset). A run stopped by a refused generation reports `BlueprintInvalidRuntimeValueError`; `refusals` says who refused it and why.
    - `refusals` RunRefusal[]: Every generation this run started that a guardrail or the provider refused, oldest first. Present only on FAILURE, and empty when no generation was refused.
      - `inference_id` string, uuid, required: The generation that was refused.
      - `code` 'INPUT_GUARDRAIL_VIOLATION' | 'CONTENT_POLICY_VIOLATION' | 'PROMPT_INTELLECTUAL_PROPERTY' | 'NO_MEDIA_GENERATED', required: The error code a refused generation fails with.
      - `guardrails` RefusalGuardrail[]: Every guardrail that blocked the generation. Empty unless `code` is `INPUT_GUARDRAIL_VIOLATION`.
        - `guardrail_id` string, uuid, required: ID of the guardrail rule that blocked the generation.
        - `name` string, required: The rule's name as it read when it judged the request.
        - `category` 'copyright_infringement' | 'ip_trademark_infringement' | 'artist_style_mimicry' | 'custom', required: What kind of guardrail refused it: one of the guardrails Layer ships, or the workspace's own.
        - `reason` string, required: Why the rule judged the request a violation. May be empty.
    - `webhook` WebhookStatusView: What a job's ``GET`` reports about the callback attached to it. The URL is echoed so a caller can tell which of its endpoints a run was aimed at; the rest is how the delivery went, which is the only place a failed delivery is visible.
      - `url` string, required: The callback URL this run was submitted with.
      - `status` 'pending' | 'delivered' | 'failed', required
      - `attempts` integer, required: How many delivery attempts have been made.
      - `last_attempt_at` string, date-time, nullable: When the last attempt was made.
      - `last_response_status` integer, nullable: HTTP status the receiver returned on the last attempt, if it responded.
      - `last_error` string, nullable: Why the last attempt did not succeed. Null once delivered.
  - `metadata` object: Whatever you sent as webhook.metadata.

## Acknowledgement `200`

Successful Response

- unknown

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/layer/apis/layer-rest-api.md) · [All operations](https://skmtc.dev/layer/apis/layer-rest-api/llms.txt) · [OpenAPI document](https://skmtc.dev/layer/apis/layer-rest-api/revisions/326f3bcdabcc?raw)
