Skip to main content

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:

  1. Authentication
  2. Organization Creation
  3. POS Integration
  4. Location Management
  5. 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

  1. When initializing the integration, if no entry_url is provided in the response, proceed with manual integration
  2. Obtain the integration code from your POS system (if you are a POS, this can likely be inferred)
  3. 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

  1. Redirect the user to the entry_url provided in the initialization response
  2. Handle the OAuth callback at your return_url
  3. 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"
}
]
}
Mock UI for Org State - POS Only

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

  1. Initialize the integration
  2. If no entry_url is provided, collect the DSP integration code
  3. 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:

  1. Display POS and DSP location details side-by-side for comparison
  2. 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"
}
]
}
Mock UI for DSP Bind

6. View Organization Locations

Endpoint

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"
}
]
}
]
}
Mock UI for Org State

Integration Status Flow

  1. pending: Initial state for non-oAuth onboardings
  2. waiting_for_oauth: During OAuth flow
  3. active: Successfully connected
  4. deprovisioned: Integration has been disconnected