Implementing Headless Onboarding
Overview
This guide explains how to integrate with the Stream Partner API to enable third-party ordering capabilities. The integration flow consists of several key steps:
- Authentication
- Organization Creation
- POS Integration
- Location Management
- DSP (Delivery Service Provider) Binding
1. Authentication
The API uses OAuth 2.0 for authentication. You'll need to obtain credentials first. Endpoint
// Authentication Request
POST /oauth/token
{
"grant_type": "client_credentials",
"client_id": "YOUR_API_KEY",
"client_secret": "YOUR_API_SECRET",
"scopes": ["onboarding"]
}
// Response
{
"access_token": "...",
"token_type": "bearer",
"refresh_token": "...",
"expires_in": 3600,
"refresh_token_expires_in": 7200,
"scopes": ["onboarding"]
}
2. Organization Creation
First step is creating an organization for your merchant: Endpoint
POST /onboarding/org
{
"name": "Merchant Name",
"provider_id": "YOUR_INTERNAL_ID",
"user": {
"email": "merchant@example.com",
"first_name": "John",
"last_name": "Doe"
}
}
// Response
{
"org_id": "...",
"user_id": "..."
}
3. POS Integration Flow
3.1. Initialize Integration
Start the POS integration process: Endpoint
POST /onboarding/integrations
{
"org_id": "ORG_ID",
"source": "YOUR_POS_SYSTEM", // e.g., "toast"
"type": "pos",
"return_url": "YOUR_CALLBACK_URL"
}
// Response
{
"onboarding": {
"_id": "ONBOARDING_ID",
"entry_url": "URL_TO_START_OAUTH", // Redirect user here if provided
"status": "pending"
}
}
3.2. Manual Integration
For POS systems that don't support OAuth or require manual integration: Endpoint
- When initializing the integration, if no
entry_url
is provided in the response, proceed with manual integration - Obtain the integration code from your POS system (if you are a POS, this can likely be inferred)
- Submit the code to complete the integration:
PUT /onboarding/integrations/{ONBOARDING_ID}
{
"code": "MANUAL_INTEGRATION_CODE"
}
// Response
{
"onboarding": {
"_id": "ONBOARDING_ID",
"status": "active",
"type": "pos",
// ... other onboarding details
}
}
3.3. OAuth Integration
For POS systems supporting OAuth: Endpoint
- Redirect the user to the
entry_url
provided in the initialization response - Handle the OAuth callback at your
return_url
- Exchange the OAuth code:
PUT /onboarding/integrations/{ONBOARDING_ID}
{
"code": "OAUTH_CODE"
}
4. Location Management
4.1. Fetch POS Locations
After integration, get available locations: Endpoint
GET /onboarding/locations?onboarding_id=ONBOARDING_ID
// Response
{
"locations": [
{
"provider_id": "POS_LOCATION_ID",
"name": "Location Name",
"address": {
"address_line_1": "123 Main St",
"postal_code": "12345",
"locality": "City",
"administrative_district_level_1": "State",
"country": "US"
},
"source": "pos_system_name"
}
]
}
4.2. Ingest Selected Locations
Import selected locations: Endpoint
This endpoint imports selected locations and their menu data from the POS system. The data stays synced via POS webhooks after initial import. You can re-sync anytime by calling this endpoint again.
POST /onboarding/locations/ingest
{
"onboarding_id": "ONBOARDING_ID",
"locations": [
{
"provider_id": "POS_LOCATION_ID"
}
]
}

5. DSP Integration
5.1. Start DSP Integration
Similar to POS integration but with type "dsp": Endpoint
POST /onboarding/integrations
{
"org_id": "ORG_ID",
"source": "DSP_NAME",
"type": "dsp",
"return_url": "YOUR_CALLBACK_URL"
}
5.2. Manual DSP Integration
Similar to manual POS integration: Endpoint
- Initialize the integration
- If no
entry_url
is provided, collect the DSP integration code - Submit the code using the same endpoint as OAuth integration
5.3. Bind DSP Locations
Connect POS locations with DSP locations: Endpoint
The binding process creates a link between locations that enables order flow. Getting this mapping wrong can result in misrouted orders.
Recommended UI flow:
- Display POS and DSP location details side-by-side for comparison
- Add confirmation step before saving
POST /onboarding/locations/bind
{
"onboarding_id": "DSP_ONBOARDING_ID",
"locations": [
{
"pos_location_id": "POS_LOCATION_ID",
"dsp_provider_id": "DSP_LOCATION_ID",
"dsp_store_name": "Store Name in DSP"
}
]
}

6. View Organization Locations
Get all locations for an organization:
This endpoint provides a way to view the current state of an organization and its locations. You can use it to verify active integrations and location statuses.
GET /onboarding/org/{ORG_ID}/locations
// Response
{
"locations": [
{
"_id": "LOCATION_ID",
"name": "Location Name",
"source": "pos_system_name",
"status": "active",
"address": {
// address details
},
"dsps": [
{
"_id": "DSP_CONNECTION_ID",
"name": "DSP Name",
"source": "dsp_name",
"status": "APPROVED"
}
]
}
]
}

Integration Status Flow
- pending: Initial state for non-oAuth onboardings
- waiting_for_oauth: During OAuth flow
- active: Successfully connected
- deprovisioned: Integration has been disconnected