Notion Callback
Exchange Notion OAuth2 code for access token.
Notion tokens do not expire, so no refresh flow is needed.
Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
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_data — pages[*].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.