Skip to content

Listing Refresh

Sent when a partner-triggered listing refresh chain terminates — either every step succeeds, or one fails. Use it to learn when a refresh you kicked off has finished, without polling.

Event type listing.refreshed
Resource type listing-refreshed-events
Triggered by POST /api/v1/listings/{id}/refresh/

When It Fires

Calling the listing refresh endpoint queues an asynchronous chain for the listing's primary channel listing:

flowchart LR
    A[POST /listings/id/refresh/] --> B[Sync listing<br/>details and availability]
    B --> C[Sync reservations]
    C --> D[Recompute automatic base price]
    D --> E{{listing.refreshed}}
    B -. any step fails .-> E

This event fires exactly once when the chain reaches a terminal state:

  • status: succeeded — the reservations sync and the automatic base-price recompute both completed.
  • status: failed — at least one step in the chain raised. The error attribute carries a short, human-readable summary.

The endpoint returns 202 Accepted immediately; this webhook is how you find out the queued work is done. Because a delivery retry re-uses the same webhook-id, dedupe on it (see idempotency).

Payload

{
  "meta": {
    "type": "listing.refreshed",
    "sent-at": "2026-07-03T12:34:56Z"
  },
  "data": {
    "type": "listing-refreshed-events",
    "id": "msg_01J9Z6M0K3QK7YV8N2C4B5A6D7",
    "attributes": {
      "status": "succeeded",
      "completed-at": "2026-07-03T12:34:56Z",
      "channel": "hostaway",
      "channel-listing-id": "external-listing-987"
    },
    "relationships": {
      "listing": {
        "data": { "type": "listings", "id": "12345" },
        "links": { "related": "https://developers.beyondpricing.com/api/v1/listings/12345/" }
      },
      "user": {
        "data": { "type": "users", "id": "456" },
        "links": { "related": "https://developers.beyondpricing.com/api/v1/users/456/" }
      },
      "account": {
        "data": { "type": "accounts", "id": "789" },
        "links": { "related": "https://developers.beyondpricing.com/api/v1/users/456/accounts/789/" }
      }
    }
  }
}
{
  "meta": {
    "type": "listing.refreshed",
    "sent-at": "2026-07-03T12:40:00Z"
  },
  "data": {
    "type": "listing-refreshed-events",
    "id": "msg_01J9Z6M0K3QK7YV8N2C4B5A6D7",
    "attributes": {
      "status": "failed",
      "completed-at": "2026-07-03T12:40:00Z",
      "channel": "hostaway",
      "channel-listing-id": "external-listing-987",
      "error": "SyncError: channel returned 503"
    },
    "relationships": {
      "listing": {
        "data": { "type": "listings", "id": "12345" }
      },
      "user": {
        "data": { "type": "users", "id": "456" }
      },
      "account": {
        "data": { "type": "accounts", "id": "789" }
      }
    }
  }
}

The meta envelope is documented in the Payload Envelope section.

data.attributes

Field Type Description
status string Terminal outcome: succeeded or failed.
completed-at string (RFC 3339) UTC timestamp when the terminal job finished.
channel string The channel the refreshed listing belongs to (e.g. airbnb, hostaway).
channel-listing-id string The refreshed listing's identifier on the channel side — the same value exposed as channel-listings[].channel-id on the listing resource. Use it to correlate the event with your own records.
error string | null Short, human-readable failure description. Present only when status is failed; stable across retries of the same delivery.

data.relationships

Every relationship carries a links.related URL you can GET for the current state of the related resource.

Relationship Description
listing The Beyond Pricing master listing that was refreshed ({ "type": "listings", "id": … }).
user The user who owns the listing ({ "type": "users", "id": … }).
account The managed account the refreshed channel listing belongs to ({ "type": "accounts", "id": … }).

Handling Tips

  • On succeeded, the listing's reservations and automatic base price are now up to date — a good moment to re-read the listing or calendar if you cache them.
  • On failed, surface or log error and consider retrying the refresh later; the failure is specific to that refresh chain, not a permanent listing state.
  • Follow the listing.links.related URL to fetch the listing's current representation rather than assuming its contents from this event.