/api/v4/social/brands/{brandId}/connections/linkGet a connection link
Returns a short-lived hosted URL that walks an end user through connecting one social platform to a brand.
Parameters
Path
| Name | Type | Required | Description |
|---|---|---|---|
| brandId | string | required | Brand UUID the connection will be attached to. |
Body
| Name | Type | Required | Description |
|---|---|---|---|
| channel | string | required | Platform to connect: `FACEBOOK`, `INSTAGRAM`, `TWITTER` (X), `LINKEDIN` or `PINTEREST`. |
| redirectUrl | string | required | Absolute https URL in your application the user is returned to when the flow finishes. Must be a URL you control. |
| errorUrl | string | optional | Absolute https URL the user is returned to if they cancel or the platform rejects the authorization. Defaults to `redirectUrl` when omitted. |
| state | string | optional | Opaque string echoed back on the return URL unchanged. Use it to correlate the return with the session that started the flow; it is not validated or interpreted. |
Sample request
Ready-to-paste body. Replace placeholder IDs and values with yours.
{ "channel": "INSTAGRAM", "redirectUrl": "https://app.example.com/social/connected", "errorUrl": "https://app.example.com/social/connect-failed", "state": "sess_9f2c1e64"}Responses
200Link generated. Redirect the end user to `url`; `expiresIn` is how many seconds it stays valid.
{ "data": { "connectSocialAccount": { "status": "success", "url": "https://social.listingsapi.com/connect/start?token=bfac8e06-8d72-4810-9c50-ae7ee12a7b52", "title": null, "token": null, "expiresIn": 900 } }}200The link could not be issued. `status` is `failed` and `title` carries the reason: most often the account is at its connection cap (`SY95042`, counted on billable connections, so recent disconnects have not freed room) or the platform is not enabled for the account (`SY95044`).
{ "data": { "connectSocialAccount": { "status": "failed", "url": null, "title": "SY95042: Connection limit reached for this account", "token": null, "expiresIn": null } }}401Unauthenticated, missing or invalid API key.
404No brand with that ID on this account (`SY95043`).
Issues a short-lived, Synup-hosted URL that connects one social platform to one
brand. You never handle the platform's OAuth credentials: redirect your end user
to the returned url, they complete the platform's consent screen and pick the
Page, board or organisation to publish to on a Synup-hosted page, and they are
returned to your redirectUrl.
This is the one Social write with a flat body. Every other write in the
Social API is wrapped in an input object; this one is not. Send channel,
redirectUrl, and optionally errorUrl and state, at the top level.
Use case: self-serve channel connection inside your product. Show the user
the five platforms, and when they pick one, call this endpoint with that
channel and a state that identifies their session. Redirect them to url.
When they land back on your redirectUrl with status=success, poll
GET /social/brands/{brandId}/connections
until the new channel appears, then let them compose their first post with
POST /social/posts.
What the user is returned to
When the flow ends, the user is sent to your redirectUrl (or errorUrl) with
query parameters appended:
https://app.example.com/social/connected ?status=success &brandId=6f2c9a41-7b0e-4d55-9a2f-3c8e1d47b902 &platform=INSTAGRAM &state=sess_9f2c1e64 &connectedAccountId=b81d5b3c-4a90-4f6a-9c11-71e0dd2fa4a7Notes.
- The link expires.
expiresIncarries its lifetime in seconds. It is single-use: issue it at the moment the user clicks "connect", not ahead of time, and never store it. If the user abandons the flow, call this endpoint again for a fresh URL. - The connection is materialised asynchronously. The user lands back on your
redirectUrla moment before the connection row exists, so a connections list read immediately on return can legitimately come back without it. Poll the connections list for a few seconds rather than treating the first empty read as a failure. - Instagram needs a Business or Creator account linked to a Facebook Page. A personal Instagram account cannot be connected, and the platform's consent screen will not offer one. If your users hit this, have them convert the account in the Instagram app and link it to the Page they manage, then re-issue the link.
TWITTERis X. The enum value stayedTWITTERfor backwards compatibility; the product is X. Platform values are uppercase enum names — sending"instagram"is rejected.redirectUrlanderrorUrlmust be absolutehttpsURLs. A relative orhttpURL is rejected withSY95049.- Connections are the metered resource. Each link draws on one account-wide
pool — 20 connections on Social Launch, 125 on Social Growth, plus five for
every $25/mo connection pack, up to a self-serve ceiling of 250. Brands
themselves are unlimited, so it is always this call, never
brand create, that runs out of room. When the
pool is full the link comes back
status: "failed"withSY95042. See Plans and add-ons and read your headroom fromGET /social/limits. - This is the Social equivalent of the location-level Facebook connect link, but the two are separate products and connections made in one are not visible in the other.
Write operation: not executed against the live account. The request and response shown are built from the API schema.
curl -X POST 'https://listingsapi.com/api/v4/social/brands/<brandId>/connections/link' \ -H "Authorization: API $LISTINGSAPI_KEY" \ -H 'Content-Type: application/json' \ -d '{ "channel": "INSTAGRAM", "redirectUrl": "https://app.example.com/social/connected", "errorUrl": "https://app.example.com/social/connect-failed", "state": "sess_9f2c1e64" }'