Skip to main content
POST
/
api
/
v1
/
workspaces
/
{workspace_id}
/
integrations
/
x-twitter
/
callback
X Callback
curl --request POST \
  --url https://api.example.com/api/v1/workspaces/{workspace_id}/integrations/x-twitter/callback \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "code": "<string>",
  "state": "<string>"
}
'
{
  "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
  "provider": "<string>",
  "account_id": "<string>",
  "account_name": "<string>",
  "status": "<string>",
  "scopes": [
    "<string>"
  ],
  "last_synced_at": "2023-11-07T05:31:56Z",
  "token_expires_at": "2023-11-07T05:31:56Z",
  "created_at": "2023-11-07T05:31:56Z",
  "has_oauth_credentials": false,
  "meta_pages": [],
  "ig_user_id": "<string>"
}

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Path Parameters

workspace_id
string<uuid>
required

Body

application/json
code
string
required
state
string
required

Response

Successful Response

Integration status — includes has_oauth_credentials so UI knows when the user has saved their own Google Cloud OAuth app credentials.

SECURITY — extra_data is deliberately NOT a field here. This model is the response_model for the workspace/brand integration-status routes (GET /brands/{id}/integrations/status, GET /workspaces/{id}/integrations/status) and for the nested WorkspaceDetailResponse.integration_credentials list. FastAPI's response_model + Pydantic from_attributes is a strict allow-list: only the fields declared below are read off the ORM row and serialized, so IntegrationCredential.extra_data is dropped before it reaches the client. That matters because OAuth providers (e.g. Meta) stash secrets in extra_datapages[*].page_access_token is written there before page selection (integration_service.py exchange_meta_code / exchange_meta_code_for_brand). Adding an extra_data field to this model would leak those page tokens to the browser — the exact class of bug fixed for the TEAM status endpoint in PR #2079. If a future edit UI needs config from extra_data, expose a NEW field carrying only the non-secret keys (mirror team_integration_service.CONFIG_PROVIDERS gating) — never the raw dict. Pinned by tests/contracts/shapes/test_integration_status_response_no_extra_data.py.

id
string<uuid>
required
provider
string
required
account_id
string | null
required
account_name
string | null
required
status
string
required
scopes
string[]
required
last_synced_at
string<date-time> | null
required
token_expires_at
string<date-time> | null
required
created_at
string<date-time>
required
has_oauth_credentials
boolean
default:false
meta_pages
MetaPageRef · object[]
ig_user_id
string | null