<!-- Markdown copy of https://docs.creatorain.com/partner-api/reference/operations/getpartnerlocation/ -->
# One store's current state, progress and next visit

GET

/locations/{partner\_location\_id}

Select code sampleFetchcURL

```js
const url = 'https://data.creatorain.com/partner/v1/locations/store_123';
const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```sh
curl --request GET \
  --url https://data.creatorain.com/partner/v1/locations/store_123 \
  --header 'Authorization: Bearer <token>'
```

-   Production (live stores; a live key is issued per partner)
-   Sandbox, for integration testing (test keys, test stores)

The store as we hold it, plus this quarter’s progress and the next confirmed creator visit. This is the read the embedded merchant dashboard is built from.

EITHER CREDENTIAL: your partner key (any store of the key), or that store’s own 30 minute token from `POST /locations/{partner_location_id}/dashboard-token`, sent as `Authorization: Bearer <token>` or `?token=<token>`. A store token presented for any other store answers `401 unauthorized`, and it answers the same 401 whether or not that other store exists.

`published_count` counts videos filmed at THIS store that are live. Videos published before 2026-09-09 carry no store and are not counted; that is a property of the data, not of the query.

`rules` is this store’s matching terms as they now stand, in the same shape `PATCH` accepts. This is the read to reconcile against if a `PATCH` response was ever lost.

## Authorizations

-   **[partnerApiKey](/partner-api/reference/#partnerapikey)**
-   **[storeTokenHeader](/partner-api/reference/#storetokenheader)**
-   **[storeTokenQuery](/partner-api/reference/#storetokenquery)**

## Parameters

### Path Parameters

**partner\_location\_id**

required

string

<= 200 characters

YOUR id for the store, as you sent it to `POST /locations`.

#### Example

```
store_123
```

## Responses

### 200

The store, its progress and its next visit.

Media typeapplication/json

object

**location\_id**

OUR id for the store. Stable, and what every other endpoint refers to it by.

string format: uuid

**partner\_location\_id**

Your id, as you sent it (trimmed).

string

**status**

`paused` means no NEW scheduling: creators are not offered the store and a new booking is refused, while bookings already confirmed are untouched. Resume opens it again. `terminated` means the contract has ended. Terminated wins over paused.

string

Allowed values: active paused terminated

**network**

A display label for the local creator pool, for example `example-pool`. Label only.

string

nullable

**dashboard\_url**

The embeddable merchant dashboard for this store, carrying a freshly minted 30 minute read-only token. Null when this deployment hosts no embedded dashboard, rather than a plausible URL pointing at nothing: an iframe rendered from a dead URL shows a merchant a blank panel, which is worse than a field you can branch on. Mint a fresh one with `POST /locations/{partner_location_id}/dashboard-token` when you render the embed.

string

nullable

**timezone**

IANA name for the store as we resolve it: the `timezone` you sent when you sent one, otherwise derived from the address. Null when neither yields one.

string

nullable

**created\_at**

RFC 3339 with the store’s offset.

string

nullable

**hours**

Whether we hold this store’s real opening hours, and where they came from. A store with no hours is still `active`: the contract exists and nothing about the enrolment failed. What it cannot do yet is take a creator booking, because our two date pickers are built from the stored week and an absent one disables both. `state: missing` is a request to chase the hours at source, which is the one place they actually exist.

object

**state**

required

string

Allowed values: missing found

**source**

required

Where the hours came from. `partner` means you sent them (`opening_hours`); the rest are our own lookups or an operator (`manual`). Null for a store never checked.

string

nullable

Allowed values: partner places gemini website manual none

**approval\_mode**

How creators are approved for this store. `auto` (the default) books matching creators straight away. `sample_review` means the merchant first approves a batch of 5 sample creators (`GET /locations/{partner_location_id}/creator-samples`); nothing starts until that decision.

string

default: auto

Allowed values: auto sample\_review

**pricing**

The store’s price for the month it is in: the same block as the quote, LOCKED when the store was confirmed. A change to `plan.videos_per_month` or `approval_mode` re-locks it from the next month (at the base price and your surcharge at that moment), shown meanwhile as `upcoming`. A later surcharge change does not move it. A store confirmed before pricing existed has no locked price: its block is worked out from the current default terms and marked `locked: false`, `source: default` (nothing is stored for it, and it shows the default creator cost range). NULL only when pricing is not set up at all.

Read with a merchant’s store token, only the merchant price is returned (`creatorain` and `surcharge` are left out).

object

**currency**

required

string

**billing\_unit**

required

string

Allowed values: published\_video

**creatorain**

required

What we bill the partner per published video. Not a fixed price.

object

**fee\_per\_video**

required

number

**creator\_cost\_per\_video**

required

Estimate range of the creator cost per video (on a quote, and on a store with no locked price; null on a locked store). The bill uses the actual cost.

object

**min**

number

**max**

number

**billed\_as**

required

string

Allowed values: creator\_cost\_plus\_fee

**surcharge**

required

object

**per\_video**

number

**plan\_surcharge**

required

The non-standard plan line, included in `merchant`. 0 / false for a standard plan.

object

**per\_video**

number

**applies**

boolean

**placeholder**

True while the amount is provisional.

boolean

**merchant**

required

object

**per\_video**

required

number

**per\_month**

required

Per\_video x videos per month. Null for a store with no plan.

number

nullable

**per\_season**

required

Per\_month x 3.

number

nullable

**season\_videos**

required

integer

nullable

**note**

required

string

**locked\_at**

When the price in force was locked (UTC). Null when `locked` is false.

string

nullable

**locked**

False for a store with no locked price, priced from the current defaults.

boolean

**source**

string

Allowed values: locked default

**upcoming**

The price from `from_month` (the store’s next month), when a re-lock is waiting.

object

**from\_month**

string

**currency**

string

**creatorain**

What we bill the partner per published video. Not a fixed price.

object

**fee\_per\_video**

required

number

**creator\_cost\_per\_video**

required

Estimate range of the creator cost per video (on a quote, and on a store with no locked price; null on a locked store). The bill uses the actual cost.

object

**min**

number

**max**

number

**billed\_as**

required

string

Allowed values: creator\_cost\_plus\_fee

**surcharge**

object

**per\_video**

number

**plan\_surcharge**

object

**per\_video**

number

**applies**

boolean

**placeholder**

boolean

**merchant**

object

**per\_video**

required

number

**per\_month**

required

Per\_video x videos per month. Null for a store with no plan.

number

nullable

**per\_season**

required

Per\_month x 3.

number

nullable

**season\_videos**

integer

nullable

**first\_visit\_business\_days**

The first-visit commitment for this store, in business days (Monday to Friday, store clock, skipping Thanksgiving Day, Christmas Day, New Year’s Day and any weekday the store’s own opening hours say it is closed), as agreed in your contract. Locked when the store is created. Null for a store created before this field existed. Show it as given.

integer

nullable

**first\_visit\_due\_by**

The store-local date the first creator visit is due by: `first_visit_business_days` counted from the day after the confirm day (`approved_at` when you sent it, otherwise the day the store was created). Locked at creation.

string format: date

nullable

**rules**

WHAT THIS STORE ASKS OF A CREATOR: the terms you set with `PATCH`, read back. Always present, ordered by attribute then operator, and `[]` for a store that asks nothing - which is what a store has until you send its first rule.

THIS IS THE SAME ARRAY `PATCH` ACCEPTS, so the obvious read-modify-write is safe: read a store, change one entry, send the array back. `value` is returned in the shape we STORED it, which is the normalised one - a bare `20000` you sent for `follower_count` reads back as `{"count": 20000, "platform": null}`, and sending that object again changes nothing.

It is deliberately NOT our internal effective rule set. Terms an operator set on our own dashboard through the older per-venue columns are not folded in here, because you can neither send nor clear those through this API and a term you cannot remove is worse than one you cannot see. Everything this array contains, `clear_rules` can remove.

Array<object>

One term this store asks of a creator.

`ethnicity`, `age_band` and `gender` are real members of our attribute list and are REFUSED with `422 validation_error` on both this API and our dashboard. Filtering paid work by a protected characteristic needs a written policy agreed with counsel, and until one exists we will not store the rule.

`follower_count` takes `gte` or `lte` and a value of `{"count": N}`, optionally with `"platform"` to say WHERE the count is measured - `{"count": 20000, "platform": "tiktok"}` means twenty thousand on TikTok, not twenty thousand in total from somebody who also has a TikTok handle. `platform` and `language` take `eq` with one value or `in` with a list; over a creator who works on several, `eq` means “this is one of hers”, never “this is her only one”.

`home_metro` (local creators only) takes `in`; `radius_miles` (within N miles of this store) takes `lte` and the miles, `25` or `{"miles": 25}`, from 1 to 500. Both are measured from this store’s own address, which we resolve when you write the rule and again when the address moves; an address we cannot place in a US city is a `422`.

`performance_index` (content performance score, 0 to 100) and `engagement_rate` (percent, `3.5` means 3.5%) take `gte` and a number. They are floors.

A creator we hold no answer for is decided by the store’s own policy, which passes by default - so adding a `language` rule today records your intent and excludes nobody until we hold languages. The follower bar, the platform, `home_metro`, `radius_miles`, `performance_index` and `engagement_rate` are the exception and always exclude a creator we cannot measure.

object

**attribute**

required

string

Allowed values: follower\_count platform language home\_metro radius\_miles performance\_index engagement\_rate

**operator**

required

string

Allowed values: gte lte in eq

**value**

required

One of:

-   [integer](#tab-panel-0-0)
-   [string](#tab-panel-0-1)
-   [Array<string>](#tab-panel-0-2)
-   [object](#tab-panel-0-3)

integer

string

Array<string>

object

**count**

integer

**platform**

string

nullable

Allowed values: instagram tiktok youtube facebook

**progress**

This store’s progress against its plan.

object

**season\_target**

Videos per SEASON (three months): `videos_per_month` x 3, following the plan in force for each month of the current season (a PATCH applies from the next month). Null when the store has no plan.

integer

nullable

**quarter\_target**

DEPRECATED. The old name of `season_target`, sent for one more release with the same value. Read `season_target`. Before this release it held the whole-term total.

integer

nullable

**published\_count**

Videos filmed at this store that are live.

integer

**booked\_count**

Confirmed visits at this store that are still in the future. Same value as `booked_upcoming`, kept so existing readers do not break; new code should read `booked_upcoming`. NOT the same as `pipeline.booked`, which counts every creator who ever booked this season, including visits already done.

integer

**booked\_upcoming**

Confirmed visits at this store that are still in the future (upcoming only; done, cancelled and past visits are not counted). `pipeline.booked` is the season total of creators who booked, so it is normally the larger of the two.

integer

**next\_visit**

The next confirmed creator visit, or null when none is booked.

object

**reservation\_id**

string format: uuid

**arrive\_at**

RFC 3339 with the STORE’S offset. The digits are the restaurant’s wall clock.

string

nullable

**timezone**

string

nullable

**notices**

How the merchant at this store is reached by email. TWO BOOLEANS AND NO ADDRESS: the address a notice goes to is an account holder’s, and this body can be read with a store dashboard token, which is a merchant’s browser credential.

object

**contact\_present**

Whether there is anybody to write to at all. False means nothing we send about this store’s bookings reaches a human, which is worth seeing before a creator turns up rather than afterwards.

boolean

**single\_channel**

True when the address the notices go to IS the store’s own published inbox: one inbox doing two jobs. It matters because a filter, a holiday auto-responder or a bounce then takes out the booking notice and the marketing conversation together, so the visit-day fallback has to be a different channel rather than a second mail.

boolean

**blocking\_reasons**

What stops this store from recruiting creators. Empty when recruiting can run. A store recruits only when the campaign is running, its opening hours are known and it is not paused or terminated. A paused store reports `store_paused` (resume it and it clears). A terminated store reports `store_terminated` and never `store_paused`: its contract is over and it cannot be resumed. When recruiting starts we send the `location.recruiting` webhook once, with `campaign_id` and `first_visit_due_by`.

Array<string>

Allowed values: hours\_missing campaign\_not\_running store\_paused store\_terminated

**pipeline**

This season’s creator pipeline for the store, as counts. Cumulative: each creator is counted once, at her furthest stage, in that stage and every earlier one, so contacted >= interested >= accepted >= booked >= visited >= posted. `declined` (said no, or no answer after follow-ups) is separate and also inside `contacted`. Contacted and interested count creators in the store’s metro area; accepted and later need a signature, booking or video at THIS store.

object

**contacted**

integer

**interested**

integer

**accepted**

integer

**booked**

Creators who booked a visit here this season, counted once each at their furthest stage, done visits included. Not the same as `progress.booked_upcoming`, which is only the confirmed visits still to come.

integer

**visited**

integer

**posted**

integer

**declined**

integer

**results**

This season’s results (guide 8.1 to 8.4). Updates with each weekly reading of the videos. Null when the store has no season yet.

object

**season\_starts\_on**

string format: date

**season\_ends\_on**

Last day of the season.

string format: date

**season\_videos\_published**

integer

**season\_videos\_target**

integer

nullable

**season\_posts**

Posts behind those videos (a cross-post is 2 posts, 1 video).

integer

**season\_plays**

integer

**posts\_read**

The season’s posts that have been read: a reading has written their numbers. At most `season_posts`; the rest have not been read yet, so they count toward no play or average.

integer

**season\_plays\_posts\_measured**

The read posts whose plays are measured, the posts `season_plays` adds up. Below `posts_read` when a platform did not publish a post’s plays. With 0, `season_plays` is 0 because nothing was counted, not because the videos got no plays.

integer

**average\_likes\_per\_video**

integer

nullable

**average\_shares\_per\_video**

Over TikTok posts only. Null with none.

integer

nullable

**average\_creator\_followers**

integer

nullable

**estimated\_new\_guests**

Estimated groups of guests who came because of the videos. Our own model, from each post’s plays, likes, comments, shares and saves and the share of the creator’s followers who are local to the store. Updates weekly, fixed at the final reading. An estimate, not a commitment. Show it with a (?) and `estimated_new_guests_help`.

integer

**estimated\_new\_guests\_note**

string

**estimated\_new\_guests\_help**

Tooltip text for the (?) icon.

string

**commitment**

The season commitment check (guide 8.4). Status is `met`, `not_met` or `pending`. Before the final reading a check is `met` once reached (provisional for averages) or `pending`; at the final reading `met` or `not_met`. Average shares is `not_measured` at the final reading when no post of the season publishes shares. First visit compares the first visit that has happened with `first_visit_due_by`.

object

**videos**

object

**value**

integer

nullable

**target**

integer

nullable

**status**

string

Allowed values: met not\_met pending not\_measured

**average\_creator\_followers**

object

**value**

integer

nullable

**target**

integer

nullable

**status**

string

Allowed values: met not\_met pending not\_measured

**season\_plays**

object

**value**

integer

nullable

**target**

integer

nullable

**status**

string

Allowed values: met not\_met pending not\_measured

**average\_likes\_per\_video**

object

**value**

integer

nullable

**target**

integer

nullable

**status**

string

Allowed values: met not\_met pending not\_measured

**average\_shares\_per\_video**

object

**value**

integer

nullable

**target**

integer

nullable

**status**

string

Allowed values: met not\_met pending not\_measured

**first\_visit**

object

**value**

string format: date

nullable

**target**

string format: date

nullable

**status**

string

Allowed values: met not\_met pending

**measured\_at**

string format: date-time

nullable

**final**

boolean

**previous\_season\_results**

The season before this one. Its final reading comes 2 weeks after it ends; from then on `final` is true and the block never changes. Null in the first season.

object

**season\_starts\_on**

string format: date

**season\_ends\_on**

Last day of the season.

string format: date

**season\_videos\_published**

integer

**season\_videos\_target**

integer

nullable

**season\_posts**

Posts behind those videos (a cross-post is 2 posts, 1 video).

integer

**season\_plays**

integer

**posts\_read**

The season’s posts that have been read: a reading has written their numbers. At most `season_posts`; the rest have not been read yet, so they count toward no play or average.

integer

**season\_plays\_posts\_measured**

The read posts whose plays are measured, the posts `season_plays` adds up. Below `posts_read` when a platform did not publish a post’s plays. With 0, `season_plays` is 0 because nothing was counted, not because the videos got no plays.

integer

**average\_likes\_per\_video**

integer

nullable

**average\_shares\_per\_video**

Over TikTok posts only. Null with none.

integer

nullable

**average\_creator\_followers**

integer

nullable

**estimated\_new\_guests**

Estimated groups of guests who came because of the videos. Our own model, from each post’s plays, likes, comments, shares and saves and the share of the creator’s followers who are local to the store. Updates weekly, fixed at the final reading. An estimate, not a commitment. Show it with a (?) and `estimated_new_guests_help`.

integer

**estimated\_new\_guests\_note**

string

**estimated\_new\_guests\_help**

Tooltip text for the (?) icon.

string

**commitment**

The season commitment check (guide 8.4). Status is `met`, `not_met` or `pending`. Before the final reading a check is `met` once reached (provisional for averages) or `pending`; at the final reading `met` or `not_met`. Average shares is `not_measured` at the final reading when no post of the season publishes shares. First visit compares the first visit that has happened with `first_visit_due_by`.

object

**videos**

object

**value**

integer

nullable

**target**

integer

nullable

**status**

string

Allowed values: met not\_met pending not\_measured

**average\_creator\_followers**

object

**value**

integer

nullable

**target**

integer

nullable

**status**

string

Allowed values: met not\_met pending not\_measured

**season\_plays**

object

**value**

integer

nullable

**target**

integer

nullable

**status**

string

Allowed values: met not\_met pending not\_measured

**average\_likes\_per\_video**

object

**value**

integer

nullable

**target**

integer

nullable

**status**

string

Allowed values: met not\_met pending not\_measured

**average\_shares\_per\_video**

object

**value**

integer

nullable

**target**

integer

nullable

**status**

string

Allowed values: met not\_met pending not\_measured

**first\_visit**

object

**value**

string format: date

nullable

**target**

string format: date

nullable

**status**

string

Allowed values: met not\_met pending

**measured\_at**

string format: date-time

nullable

**final**

boolean

#### Example

```json
{
  "partner_location_id": "store_123",
  "status": "active",
  "network": "example-pool",
  "timezone": "America/Los_Angeles",
  "created_at": "2026-09-10T13:22:00-07:00",
  "hours": {
    "state": "missing",
    "source": "partner"
  },
  "approval_mode": "auto",
  "pricing": {
    "currency": "USD",
    "billing_unit": "published_video",
    "creatorain": {
      "fee_per_video": 10,
      "creator_cost_per_video": {
        "min": 20,
        "max": 40
      },
      "billed_as": "creator_cost_plus_fee"
    },
    "surcharge": {
      "per_video": 10
    },
    "plan_surcharge": {
      "per_video": 5,
      "applies": false,
      "placeholder": true
    },
    "merchant": {
      "per_video": 100,
      "per_month": 200,
      "per_season": 600
    },
    "season_videos": 6,
    "source": "locked",
    "upcoming": {
      "from_month": "2026-11",
      "creatorain": {
        "fee_per_video": 10,
        "creator_cost_per_video": {
          "min": 20,
          "max": 40
        },
        "billed_as": "creator_cost_plus_fee"
      },
      "merchant": {
        "per_video": 100,
        "per_month": 200,
        "per_season": 600
      }
    }
  },
  "first_visit_due_by": "2026-10-06",
  "rules": [
    {
      "attribute": "follower_count",
      "operator": "gte",
      "value": {
        "count": 20000,
        "platform": "tiktok"
      }
    },
    {
      "attribute": "platform",
      "operator": "eq",
      "value": "tiktok"
    }
  ],
  "progress": {
    "season_target": 6,
    "quarter_target": 6,
    "published_count": 2,
    "booked_count": 1,
    "booked_upcoming": 1
  },
  "next_visit": {
    "arrive_at": "2026-09-14T19:00:00-07:00",
    "timezone": "America/Los_Angeles"
  },
  "blocking_reasons": [
    "hours_missing"
  ],
  "pipeline": {
    "contacted": 38,
    "interested": 7,
    "accepted": 3,
    "booked": 1,
    "visited": 0,
    "posted": 0,
    "declined": 4
  },
  "results": {
    "season_starts_on": "2026-10-01",
    "season_ends_on": "2026-12-31",
    "season_videos_published": 3,
    "season_videos_target": 9,
    "season_posts": 4,
    "season_plays": 58400,
    "posts_read": 4,
    "season_plays_posts_measured": 4,
    "average_likes_per_video": 785,
    "average_shares_per_video": 106,
    "average_creator_followers": 13070,
    "estimated_new_guests": 24,
    "estimated_new_guests_note": "Estimate from video engagement data. Not a commitment.",
    "commitment": {
      "videos": {
        "value": 58400,
        "target": 60000,
        "status": "met"
      },
      "average_creator_followers": {
        "value": 58400,
        "target": 60000,
        "status": "met"
      },
      "season_plays": {
        "value": 58400,
        "target": 60000,
        "status": "met"
      },
      "average_likes_per_video": {
        "value": 58400,
        "target": 60000,
        "status": "met"
      },
      "average_shares_per_video": {
        "value": 58400,
        "target": 60000,
        "status": "met"
      },
      "first_visit": {
        "value": "2026-10-03",
        "target": "2026-10-06",
        "status": "met"
      }
    },
    "measured_at": "2026-11-09T02:00:00Z",
    "final": false
  },
  "previous_season_results": {
    "season_starts_on": "2026-10-01",
    "season_ends_on": "2026-12-31",
    "season_videos_published": 3,
    "season_videos_target": 9,
    "season_posts": 4,
    "season_plays": 58400,
    "posts_read": 4,
    "season_plays_posts_measured": 4,
    "average_likes_per_video": 785,
    "average_shares_per_video": 106,
    "average_creator_followers": 13070,
    "estimated_new_guests": 24,
    "estimated_new_guests_note": "Estimate from video engagement data. Not a commitment.",
    "commitment": {
      "videos": {
        "value": 58400,
        "target": 60000,
        "status": "met"
      },
      "average_creator_followers": {
        "value": 58400,
        "target": 60000,
        "status": "met"
      },
      "season_plays": {
        "value": 58400,
        "target": 60000,
        "status": "met"
      },
      "average_likes_per_video": {
        "value": 58400,
        "target": 60000,
        "status": "met"
      },
      "average_shares_per_video": {
        "value": 58400,
        "target": 60000,
        "status": "met"
      },
      "first_visit": {
        "value": "2026-10-03",
        "target": "2026-10-06",
        "status": "met"
      }
    },
    "measured_at": "2026-11-09T02:00:00Z",
    "final": false
  }
}
```

### 401

`unauthorized`. A missing, malformed, unknown or revoked key; or an invalid, expired or wrong-store dashboard token. One answer for every case on purpose: the holder of a bad credential learns nothing from the difference.

Media typeapplication/json

object

**error**

required

object

**code**

required

The stable value to branch on.

string

Allowed values: unauthorized forbidden\_ip rate\_limited validation\_error location\_already\_exists location\_not\_found location\_terminated reservation\_not\_found conflict internal\_error

**message**

required

A human sentence. Copy, not contract; it may be reworded.

string

**field**

The request field at fault, dotted for a nested one (`plan.term_months`).

string

#### Example

```json
{
  "error": {
    "code": "unauthorized"
  }
}
```

### 404

`location_not_found`. No store of this key carries that `partner_location_id`.

Media typeapplication/json

object

**error**

required

object

**code**

required

The stable value to branch on.

string

Allowed values: unauthorized forbidden\_ip rate\_limited validation\_error location\_already\_exists location\_not\_found location\_terminated reservation\_not\_found conflict internal\_error

**message**

required

A human sentence. Copy, not contract; it may be reworded.

string

**field**

The request field at fault, dotted for a nested one (`plan.term_months`).

string

#### Example

```json
{
  "error": {
    "code": "unauthorized"
  }
}
```

### 429

`rate_limited`. Over this key’s requests-per-minute ceiling.

Media typeapplication/json

object

**error**

required

object

**code**

required

The stable value to branch on.

string

Allowed values: unauthorized forbidden\_ip rate\_limited validation\_error location\_already\_exists location\_not\_found location\_terminated reservation\_not\_found conflict internal\_error

**message**

required

A human sentence. Copy, not contract; it may be reworded.

string

**field**

The request field at fault, dotted for a nested one (`plan.term_months`).

string

#### Example

```json
{
  "error": {
    "code": "unauthorized"
  }
}
```
