Skip to content

Audience Syncs

Audience syncs push a graph8 audience (contact list) to an ad platform and keep it in sync on a cadence. graph8 supports four platforms: Meta (Facebook/Instagram custom audiences), LinkedIn (Matched Audiences), Google Ads (Customer Match), and X (Tailored Audiences).

Each sync config has a mode:

  • mirror - keep the platform audience exactly in sync with the source list (adds new members, removes dropped members).
  • append_only - only add new members; never remove.

A worker re-runs each sync on its refresh_cadence_hours. You can also trigger a sync manually.

EndpointMethodDescription
/audience-syncsGETList all sync configs for the org
/audience-syncsPOSTCreate a new sync config
/audience-syncs/{id}GETGet a single sync config
/audience-syncs/{id}PATCHUpdate a sync config
/audience-syncs/{id}DELETESoft delete a sync config
/audience-syncs/{id}/triggerPOSTManually trigger a sync run
/audience-syncs/{id}/runsGETList recent sync runs
/audience-syncs/{id}/errorsGETList failed sync runs only

For machine-readable schemas see the interactive API docs.


List Audience Syncs

GET /audience-syncs

Returns every sync config for the authenticated org.

Example

Terminal window
curl "https://be.graph8.com/api/v1/audience-syncs" \
-H "Authorization: Bearer $API_KEY"

Response

{
"data": [
{
"id": 12,
"audience_id": 5,
"platform": "meta",
"platform_audience_name": "Q2 Outbound - Mirror",
"mode": "mirror",
"refresh_cadence_hours": 24,
"is_active": true,
"status": "active",
"last_sync_at": "2026-04-15T08:00:00Z",
"created_at": "2026-04-01T10:00:00Z"
}
]
}

Create Audience Sync

POST /audience-syncs

Create a new sync config. Returns 409 Conflict if a config already exists for the same audience_id + platform.

Request Body

FieldTypeRequiredDescription
audience_idintegerYesSource list ID (must be > 0)
platformstringYesOne of meta, linkedin, google, x
platform_audience_namestringNoDisplay name on the ad platform (max 255)
modestringNomirror (default) or append_only
refresh_cadence_hoursintegerNo0-720, default 24
platform_configobjectNoPlatform-specific config (e.g. ad account ID, OAuth scopes)
suppression_list_idsinteger[]NoLists whose members should be excluded

Example

Terminal window
curl -X POST "https://be.graph8.com/api/v1/audience-syncs" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"audience_id": 5,
"platform": "meta",
"platform_audience_name": "Q2 Outbound",
"mode": "mirror",
"refresh_cadence_hours": 24,
"platform_config": {"ad_account_id": "act_1234567890"}
}'

Response 201 Created

Returns the same shape as a list item.

Errors

StatusMeaning
409A sync config already exists for this audience + platform
422platform not in allowed set, or mode invalid

Get Audience Sync

GET /audience-syncs/{config_id}

Returns a single sync config by ID.

Example

Terminal window
curl "https://be.graph8.com/api/v1/audience-syncs/12" \
-H "Authorization: Bearer $API_KEY"

Errors

StatusMeaning
404Sync config not found

Update Audience Sync

PATCH /audience-syncs/{config_id}

Partial update. Send only the fields you want to change.

Request Body

FieldTypeDescription
modestringmirror or append_only
refresh_cadence_hoursinteger0-720
is_activebooleanPause/unpause without deleting
suppression_list_idsinteger[]Replace suppression list set

Example

Terminal window
curl -X PATCH "https://be.graph8.com/api/v1/audience-syncs/12" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"is_active": false}'

Delete Audience Sync

DELETE /audience-syncs/{config_id}

Soft delete. The platform audience is not removed from the ad platform - graph8 simply stops syncing.

Response

{ "data": { "status": "deleted", "id": 12 } }

Trigger Audience Sync

POST /audience-syncs/{config_id}/trigger

Run the sync immediately, outside of its scheduled cadence. Returns the sync result payload (members added/removed counts).

Example

Terminal window
curl -X POST "https://be.graph8.com/api/v1/audience-syncs/12/trigger" \
-H "Authorization: Bearer $API_KEY"

Errors

StatusMeaning
500Underlying ad platform returned an error - check /runs or /errors for the message

List Sync Runs

GET /audience-syncs/{config_id}/runs

Returns recent runs for a config (success and failure both).

Query Parameters

ParameterTypeDefaultDescription
limitinteger20Max runs to return (1-100)

Response

{
"data": [
{
"id": 4521,
"started_at": "2026-04-15T08:00:00Z",
"finished_at": "2026-04-15T08:00:14Z",
"status": "success",
"members_added": 12,
"members_removed": 3,
"total_members": 1450,
"error_message": null
}
]
}

List Sync Errors

GET /audience-syncs/{config_id}/errors

Same shape as /runs, filtered to status = "failed". Use this when surfacing failures in your dashboard.

Query Parameters

ParameterTypeDefaultDescription
limitinteger20Max errors to return (1-100)

Response

{
"data": [
{
"id": 4520,
"started_at": "2026-04-15T07:30:00Z",
"error_message": "Meta API: invalid access token",
"details": { "config_id": 12, "status": "failed" }
}
]
}