Skip to content

Account Refreshed

Sent when the background listing sync started by refreshing a managed account reaches a terminal state — every listing the refresh considered has been re-pulled from the channel, or the sync failed. Use it to learn when a refresh you triggered is done, without polling.

Event type account.refreshed
Resource type account-refreshed-events
Triggered by POST /api/v1/users/{user_id}/accounts/{account_id}/refresh/

When It Fires

The refresh endpoint enqueues the sync and returns 202 Accepted right away. The real work happens afterwards, in the background:

flowchart LR
    A[POST /users/id/accounts/id/refresh/] --> B[202 Accepted]
    B --> C[Background: re-pull listings<br/>from the channel]
    C --> D{{account.refreshed}}
    C --> E[Reservations refresh<br/>continues in the background]

This event fires exactly once per accepted refresh, when the listing sync reaches a terminal state:

  • status: succeeded — every listing the refresh considered synced without error.
  • status: failed — at least one listing failed, or the sync itself did not complete. The error attribute carries a short, human-readable summary.

Because a delivery retry re-uses the same webhook-id, dedupe on it (see idempotency).

Listings only — reservations are still in flight

The event describes the listing sync. Each listing's reservations are refreshed by an independent background job that outlives this event, so reservations may still be arriving when it is delivered. There is no reservation-completion event today.

Skipped listings are not counted

recent_sync_threshold_minutes (default 60) tells the refresh to skip listings synced within that window. Skipped listings never enter the sync, so they are not counted in nb-listings-synced. A refresh that skips every listing is still succeeded, with nb-listings-synced of 0. The threshold the refresh ran with is echoed back as recent-sync-threshold-minutes so you can interpret the count. Pass recent_sync_threshold_minutes=0 to force a full refresh.

status is all-or-nothing

succeeded requires every considered listing to sync cleanly. One failure out of 500 yields status: failed with nb-listings-synced: 499. Read the counts, not just the status.

Payload

{
  "meta": {
    "type": "account.refreshed",
    "sent-at": "2026-07-10T12:34:56Z"
  },
  "data": {
    "type": "account-refreshed-events",
    "id": "msg_01J9Z6M0K3QK7YV8N2C4B5A6D7",
    "attributes": {
      "status": "succeeded",
      "completed-at": "2026-07-10T12:34:56Z",
      "channel": "hostaway",
      "nb-listings-synced": 40,
      "nb-listings-failed": 0,
      "recent-sync-threshold-minutes": 60
    },
    "relationships": {
      "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": "account.refreshed",
    "sent-at": "2026-07-10T12:40:00Z"
  },
  "data": {
    "type": "account-refreshed-events",
    "id": "msg_01J9Z6M0K3QK7YV8N2C4B5A6D7",
    "attributes": {
      "status": "failed",
      "completed-at": "2026-07-10T12:40:00Z",
      "channel": "hostaway",
      "nb-listings-synced": 38,
      "nb-listings-failed": 2,
      "recent-sync-threshold-minutes": 0,
      "error": "2 listing(s) failed to sync"
    },
    "relationships": {
      "user": {
        "data": { "type": "users", "id": "456" }
      },
      "account": {
        "data": { "type": "accounts", "id": "789" }
      }
    }
  }
}
{
  "meta": {
    "type": "account.refreshed",
    "sent-at": "2026-07-10T12:40:00Z"
  },
  "data": {
    "type": "account-refreshed-events",
    "id": "msg_01J9Z6M0K3QK7YV8N2C4B5A6D7",
    "attributes": {
      "status": "failed",
      "completed-at": "2026-07-10T12:40:00Z",
      "channel": "hostaway",
      "nb-listings-synced": 40,
      "nb-listings-failed": null,
      "recent-sync-threshold-minutes": 60,
      "error": "The account's listing sync did not complete successfully"
    },
    "relationships": {
      "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 refresh reached its terminal state.
channel string The channel the account is connected to (e.g. airbnb, hostaway).
nb-listings-synced integer Number of listings the refresh successfully re-synced. Excludes listings skipped as recently synced.
nb-listings-failed integer | null Number of listings the refresh could not sync. Always present; 0 when status is succeeded. It is null when the sync did not run to completion (an infrastructure failure, or a channel-wide error), so the per-listing count is unknown — in that case nb-listings-synced reports how many listings exist on the account.
recent-sync-threshold-minutes integer The threshold the refresh ran with, echoed from the request. Listings synced within this many minutes were skipped; 0 means none were.
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
user The user the account belongs to ({ "type": "users", "id": … }).
account The managed account that was refreshed ({ "type": "accounts", "id": … }).

Handling Tips

  • On succeeded, the account's listings reflect the channel as of completed-at — a good moment to GET /listings/ for the user.
  • On failed with a numeric nb-listings-failed, some listings did sync: read the listings you have and re-trigger the refresh for the rest. A null means the sync did not finish and nothing can be concluded about individual listings.
  • If nb-listings-synced is lower than you expect, check recent-sync-threshold-minutes — those listings were already fresh.
  • Reservation data is not guaranteed to be current when this event arrives.