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. Theerrorattribute 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 ofcompleted-at— a good moment toGET/listings/for the user. - On
failedwith a numericnb-listings-failed, some listings did sync: read the listings you have and re-trigger the refresh for the rest. Anullmeans the sync did not finish and nothing can be concluded about individual listings. - If
nb-listings-syncedis lower than you expect, checkrecent-sync-threshold-minutes— those listings were already fresh. - Reservation data is not guaranteed to be current when this event arrives.