---
title: "Everything observed since one placement"
method: GET
path: "/v1/orders/{order_id}/outcome"
tags: ["Orders"]
---

# Everything observed since one placement

`GET /v1/orders/{order_id}/outcome`

## Request

- Base URL: `https://api.placementapi.com`
- URL: `https://api.placementapi.com/v1/orders/{order_id}/outcome`
- Auth: HTTP bearer

Per-keyword rank series across checkpoints, SERP churn, visibility before/after, survival checks, and a confidence with a note. Recomputed on read when the stored row is over an hour old. `outcome` is null with a note until tracking has started.

## Path parameters

- `order_id` string, required

## Response `200`

OK

- object
  - `order_id` string
  - `status` 'ordered' | 'awaiting_content' | 'content_revision_requested' | 'awaiting_operator' | 'submitted_to_vendor' | 'delivered' | 'cancelled' | 'refunded' | 'failed'
  - `outcome` Outcome, nullable: Everything observed since a placement. Checkpoints: baseline_order, baseline_delivery, d7, d30, d60, d90, d180, d365. Observational: a rank that moved is a fact; that this link moved it is not established. Never say 'caused'.
    - `order_id` string
    - `target_url` string
    - `site_id` string, nullable
    - `delivered_at` string, nullable
    - `days_observed` integer, nullable
    - `latest_checkpoint` string, nullable
    - `keywords` OutcomeKeyword[]
      - `keyword` string
      - `baseline` integer, nullable
      - `latest` integer, nullable
      - `latest_checkpoint` string, nullable
      - `delta` integer, nullable: baseline − latest: positive means it moved up.
      - `best` integer, nullable
      - `series` object[]
        - `checkpoint` string
        - `rank` integer, nullable
        - `observed_at` string
    - `keywords_tracked` integer
    - `keywords_improved` integer
    - `keywords_declined` integer
    - `entered_top10` integer
    - `median_delta` number, nullable
    - `volatility_proxy` number, nullable
    - `serp_churn` number, nullable: Share of the baseline top-10 domains no longer in the latest top 10.
    - `visibility` object
      - `baseline_traffic` number, nullable
      - `latest_traffic` number, nullable
      - `baseline_keywords` integer, nullable
      - `latest_keywords` integer, nullable
    - `survival` object
      - `live` boolean, nullable
      - `checks` integer
      - `last_checked` string, nullable
      - `first_missing_at` string, nullable
    - `confidence` 'low' | 'medium' | 'high': About the window, not the size of the movement: under 30 days is noise; one keyword is an anecdote; churn ≥50% says the SERP moved.
    - `confidence_note` string
    - `computed_at` string, date-time
  - `note` string

## Other responses

- `401`: Missing, malformed or revoked Bearer credential: `{ error: "unauthorized" }`.
- `403`: `insufficient_scope` when the key lacks the `order` scope; `customer_key_required` when the operator token is used where a customer must be attributable.
- `404`: `order_not_found`.
- `503`: `server_misconfigured` when the store is not configured; `upstream_unfunded` when the measurement provider's prepaid balance is exhausted (fresh profiles, gap maps and SERPs pause; cached results and catalogue are unaffected); `upstream_unavailable` on a provider error; `payments_unavailable` when card payments are not configured.

---

[API](https://skmtc.dev/placementapi/apis/placement-api.md) · [All operations](https://skmtc.dev/placementapi/apis/placement-api/llms.txt) · [OpenAPI document](https://skmtc.dev/placementapi/apis/placement-api/revisions/fc4e7866eaf7?raw)
