Skip to main content
A Seam integration starts when a user signs in to their device provider and gives your platform permission to access their account. The easiest way to support this is through OAuth2, because it gives users a familiar login screen and lets your API issue secure, long-lasting tokens without exposing passwords.

OAuth2 with Access + Refresh Tokens

Your API should use the standard OAuth2 Authorization Code flow.

1. Authorization request launches the flow

As the first step, Seam makes a GET request to your authorization URL. This should show the user a login screen from your service.

Example authorization request

GET https://api.provider.com/oauth/authorize?
  response_type=code&
  client_id=seam_prod_123&
  redirect_uri=https://example.com/oauth_redirect&
  scope=locks.read%20locks.write&
  prompt=login&
  state=xyz123
Key expectations:
  • prompt=login must force the user to re-authenticate even if they have an existing session.
  • redirect_uri should match one of the URIs Seam registers with your platform.
  • state must be returned unchanged to prevent CSRF.

After Seam sends the authorization request in step 1, your service should display a login and consent screen. The user signs in, reviews what Seam will be able to access, and decides whether to continue.
Example login screen from Google
Example consent screen from Google
Your UI should:
  • ask the user to log in
  • clearly show what Seam will access
  • allow them to approve or deny
This step should feel identical to signing into your own product.

3. Redirect back to Seam with a code

After approval, redirect the browser back to the provided redirect URL:
https://example.com/oauth_redirect
Your service must append the authorization code (code) and state:
https://example.com/oauth_redirect?
  code=abc123_code_from_provider&
  state=xyz123
Key expectations:
  • the redirect URL must exactly match one that Seam registered with your platform.
  • code is the temporary value Seam will exchange for tokens.
  • state must match what Seam originally sent in Step 1.

4. Exchange the code for tokens

Seam will exchange the authorization code for tokens:
POST https://api.provider.com/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&
code=abc123_code_from_callback&
redirect_uri=https://connect.getseam.com/oauth/callback&
client_id=seam_prod_123&
client_secret=shhh_very_secret
Expected response:
{
  "access_token": "ya29.a0ARt76ExampleAccess",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "1//0exampleRefreshToken",
  "user_id": "provider_user_491829"
}
Best practices:
  • access_token expires quickly (1h is typical)
  • refresh_token lasts long and is stable
  • user_id must be stable across all future authentications

5. Calling your API with the access token

Seam can call your APIs using the access token. A common way is to do it using the the standard Authorization header:
GET https://api.provider.com/v1/locks/123
Authorization: Bearer ya29.a0ARt76ExampleAccess

6. Refreshing tokens over time

Seam refreshes tokens frequently, sometimes from multiple workflows running at once.
POST https://api.provider.com/oauth/tokenContent-Type:
application/x-www-form-urlencoded grant_type=refresh_token&
refresh_token=1//0exampleRefreshToken& client_id=seam_prod_123&
client_secret=shhh_very_secret
Expected response:
{
  "access_token": "ya29.newAccessTokenHere",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "1//0exampleRefreshToken",
  "user_id": "provider_user_491829"
}

Key requirements

  • issue a new access token
  • keep existing unexpired access tokens valid
  • keep the refresh token usable until Seam rotates it

Additional integration requirements

Stable User Identifier

Seam needs a permanent, account-level ID in every OAuth response so it can reconnect accounts and avoid duplicates. This ID must:
  • remain the same for the lifetime of the account
  • not depend on email addresses
  • not change when tokens or sessions rotate
Example access token response:
{
  "user_id": "provider_user_491829", // stable account identifier
  "access_token": "ya29.a0ARt76ExampleAccess",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "1//0exampleRefreshToken"
}

Multiple Redirect URLs

Seam generally likes to use separate redirect URIs for production, staging, and local development. It’s preferable if your provider allows registering multiple URLs. Typical examples:
https://connect.getseam.com/oauth/callback
https://staging.connect.getseam.com/oauth/callback
http://localhost:3020/oauth/callback

Token Stability Requirements

Seam may refresh tokens from multiple workflows at the same time, so refreshing can’t interrupt active requests. Requirements:
  • issue a new access token during refresh
  • let previously issued, unexpired access tokens keep working
  • keep the refresh token valid until Seam rotates it
  • do not force the user to sign in again or return 401s after refresh
This protects long-running provisioning jobs, onboarding polling, and parallel credential updates from unexpected failures.