📢 Important Notice
OAuth 1.0 will be deprecated and discontinued on July 1, 2026. All integrations must migrate to OAuth 2.0 before this date to maintain API access.
Timeline
-
Phase 1 (January 2026 - June 2026): Migration period with both OAuth 1.0 and 2.0 available
- Deprecation warnings in all OAuth 1.0 API responses and in Tripleseat Dashboard
- Phase 2 (July 1, 2026): OAuth 1.0 sunset - complete shutdown
Why Are We Migrating to OAuth 2.0?
- Simplified Integration: Easier implementation with standard libraries and using bearer tokens over HTTPS instead of complex signature generation
- Improved Security: OAuth 2.0 allows more granular resource access via scoping and permissions
- Better Token Management: Refresh tokens for seamless re-authentication
- Industry Standard: OAuth 2.0 is the modern standard adopted by all major platforms
- Enhanced Features: Support for different grant types and scopes
- Easier for Customers: Since partners and integrators only need to create a single OAuth 2.0 app in their sandbox, customers will just need to go through the authorization flow and will not need to configure an app themselves or pass any credentials.
Key Differences
OAuth 1.0 (Current/Legacy)
- Authentication: Signature-based with consumer key/secret
- Flow: Three-legged with request tokens
- Complexity: Requires HMAC-SHA1 signature generation
- Token Type: Long-lived access tokens
- Endpoints: /oauth/*
- Credential Sharing: Customers need to pass secure credentials to integrators
OAuth 2.0
- Authentication: Bearer tokens over HTTPS
- Flow: Authorization code with refresh tokens
- Complexity: Simple token exchange
- Token Type: Short-lived access tokens with refresh capability
- Endpoints: /oauth2/*
-
Credential Sharing: No credentials sharing. Customers authorize against the integrator's OAuth 2.0 application.
Migration Steps
Step 1: Create OAuth 2.0 Application
- Log in to Tripleseat with admin credentials
- Navigate to: Settings → Tripleseat API & Webhooks (under the Resources section)
- Under Tripleseat API OAuth 2.0 Client Applications, you can create and manage your OAuth 2.0 applications
- Click View or Edit Client Applications then create a new OAuth 2.0 application using the + New Application button. Enter the following information:
- Name: [Your Integration Name]
- Description: [Your Integration Description]
- Information URL: Your company/integration website
- Redirect URL: Your OAuth callback URL
-
Your required application scopes
-
Save and copy the resulting credentials:
- UID: Your new OAuth 2.0 client ID
- Secret: Your new OAuth 2.0 client secret
Step 2: Update Your Authentication Flow
Replace your OAuth 1.0 authentication with OAuth 2.0:
OAuth 2.0 Authorization Flow
-
Redirect user to authorization URL:
https://login.tripleseat.com/oauth2/authorize? client_id=YOUR_CLIENT_ID& redirect_uri=YOUR_REDIRECT_URI& response_type=code& scope=read%20write - User authorizes your application
-
Exchange authorization code for access token:
POST https://api.tripleseat.com/oauth2/token Content-Type: application/x-www-form-urlencoded grant_type=authorization_code& code=AUTHORIZATION_CODE& client_id=YOUR_CLIENT_ID& client_secret=YOUR_CLIENT_SECRET& redirect_uri=YOUR_REDIRECT_URI -
Response includes access and refresh tokens
{ "access_token": "YOUR_ACCESS_TOKEN", "token_type": "Bearer", "expires_in": 7200, "refresh_token": "YOUR_REFRESH_TOKEN", "scope": "read write", "created_at": 1234567890 }
Step 3: Update API Requests
OAuth 1.0 (Old Way)
GET /api/v1/locations HTTP/1.1
Host: api.tripleseat.com
Authorization: OAuth oauth_consumer_key="KEY",
oauth_token="TOKEN",
oauth_signature_method="HMAC-SHA1",
oauth_signature="SIGNATURE",
oauth_timestamp="1234567890",
oauth_nonce="NONCE",
oauth_version="1.0"OAuth 2.0 (New Way)
GET /api/v1/locations HTTP/1.1
Host: api.tripleseat.com
Authorization: Bearer YOUR_ACCESS_TOKENStep 4: Implement Token Refresh
OAuth 2.0 access tokens expire after 2 hours. Use refresh tokens to get new access tokens:
POST https://api.tripleseat.com/oauth2/token
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token&
refresh_token=YOUR_REFRESH_TOKEN&
client_id=YOUR_CLIENT_ID&
client_secret=YOUR_CLIENT_SECRET
Migrating Customers with Existing OAuth 1.0 Credentials
If you are a partner with customers who already have active OAuth 1.0 integrations, you can exchange their existing OAuth 1.0 consumer credentials for OAuth 2.0 tokens without requiring the customer to go through the authorization flow. This allows you to migrate existing customers seamlessly in the background.
Prerequisites:
- You have created an OAuth 2.0 application (see Step 1 above)
- You have the customer's existing OAuth 1.0 Consumer Key and Consumer Secret (from their Client Application in Tripleseat)
- The customer has at least one active site in Tripleseat
Token Exchange Request
Send a POST request to the token endpoint using the oauth1_exchange grant type:
POST https://api.tripleseat.com/oauth2/token
Content-Type: application/x-www-form-urlencoded
grant_type=oauth1_exchange&
client_id=YOUR_OAUTH2_CLIENT_ID&
client_secret=YOUR_OAUTH2_CLIENT_SECRET&
consumer_key=CUSTOMER_OAUTH1_CONSUMER_KEY&
consumer_secret=CUSTOMER_OAUTH1_CONSUMER_SECRETSuccessful Response:
{
"access_token": "YOUR_ACCESS_TOKEN",
"token_type": "Bearer",
"expires_in": 7200,
"refresh_token": "YOUR_REFRESH_TOKEN",
"scope": "events:read events:write leads:read leads:write ...",
"created_at": 1234567890
}The returned scopes are determined by your OAuth 2.0 application's configuration. The token is issued on behalf of the site creator associated with the customer's account.
Important Notes:
- One-time exchange: After receiving your OAuth 2.0 tokens, use the refresh_token to renew access going forward. You do not need to repeat the exchange.
- Token expiration: Access tokens expire after 2 hours. Use the refresh token to obtain a new access token (see Step 4 above).
- Public vs. private applications: Public OAuth 2.0 applications can exchange credentials for any customer. Private applications can only exchange credentials for the customer that owns the application.
-
No customer action required: This exchange happens server-to-server. The customer does not need to log in or authorize anything.
Code Examples
Ruby
OAuth 1.0 (Old)
require 'oauth'
consumer = OAuth::Consumer.new(
CONSUMER_KEY,
CONSUMER_SECRET,
site: "https://api.tripleseat.com"
)
access_token = OAuth::AccessToken.new(consumer, TOKEN, SECRET)
response = access_token.get('/api/v1/locations')OAuth 2.0 (New)
require 'oauth2'
client = OAuth2::Client.new(
CLIENT_ID,
CLIENT_SECRET,
site: 'https://api.tripleseat.com',
authorize_url: 'https://login.tripleseat.com/oauth2/authorize', # Absolute URL for login domain
token_url: '/oauth2/token' # Relative URL, uses api.tripleseat.com
)
# Get authorization URL - will use login.tripleseat.com
auth_url = client.auth_code.authorize_url(redirect_uri: REDIRECT_URI)
# Exchange code for token - will use api.tripleseat.com
token = client.auth_code.get_token(
authorization_code,
redirect_uri: REDIRECT_URI
)
# Make API request - uses api.tripleseat.com
response = token.get('/api/v1/locations')
# Refresh token when expired
if token.expired?
new_token = token.refresh!
endOAuth 1.0 Exchange (Migration)
require 'oauth2'
client = OAuth2::Client.new(
CLIENT_ID,
CLIENT_SECRET,
site: 'https://api.tripleseat.com',
token_url: '/oauth2/token'
)
# Exchange existing OAuth 1.0 credentials for OAuth 2.0 tokens
token = client.get_token(
grant_type: 'oauth1_exchange',
consumer_key: CUSTOMER_OAUTH1_CONSUMER_KEY,
consumer_secret: CUSTOMER_OAUTH1_CONSUMER_SECRET
)
# Make API request
response = token.get('/api/v1/locations')
# Refresh token when expired
if token.expired?
new_token = token.refresh!
endOAuth 1.0 Exchange (Migration)
import requests
# Exchange existing OAuth 1.0 credentials for OAuth 2.0 tokens
response = requests.post(
'https://api.tripleseat.com/oauth2/token',
data={
'grant_type': 'oauth1_exchange',
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'consumer_key': CUSTOMER_OAUTH1_CONSUMER_KEY,
'consumer_secret': CUSTOMER_OAUTH1_CONSUMER_SECRET
}
)
token = response.json()
access_token = token['access_token']
refresh_token = token['refresh_token']
# Make API request
api_response = requests.get(
'https://api.tripleseat.com/api/v1/locations',
headers={'Authorization': f'Bearer {access_token}'}
)Python
OAuth 1.0 (Old)
from requests_oauthlib import OAuth1Session
oauth = OAuth1Session(
CONSUMER_KEY,
client_secret=CONSUMER_SECRET,
resource_owner_key=TOKEN,
resource_owner_secret=TOKEN_SECRET
)
response = oauth.get('https://api.tripleseat.com/api/v1/locations')OAuth 2.0 (New)
import requests
from requests_oauthlib import OAuth2Session
# Setup OAuth2 session
oauth = OAuth2Session(
CLIENT_ID,
redirect_uri=REDIRECT_URI,
scope=['read', 'write']
)
# Get authorization URL
authorization_url, state = oauth.authorization_url(
'https://login.tripleseat.com/oauth2/authorize'
)
# Exchange code for token
token = oauth.fetch_token(
'https://api.tripleseat.com/oauth2/token',
authorization_response=callback_url,
client_secret=CLIENT_SECRET
)
# Make API request
response = oauth.get('https://api.tripleseat.com/api/v1/locations')
# Refresh token
if token_is_expired:
token = oauth.refresh_token(
'https://api.tripleseat.com/oauth2/token',
refresh_token=token['refresh_token'],
client_id=CLIENT_ID,
client_secret=CLIENT_SECRET
)OAuth 1.0 Exchange (Migration)
import requests
# Exchange existing OAuth 1.0 credentials for OAuth 2.0 tokens
response = requests.post(
'https://api.tripleseat.com/oauth2/token',
data={
'grant_type': 'oauth1_exchange',
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'consumer_key': CUSTOMER_OAUTH1_CONSUMER_KEY,
'consumer_secret': CUSTOMER_OAUTH1_CONSUMER_SECRET
}
)
token = response.json()
access_token = token['access_token']
refresh_token = token['refresh_token']
# Make API request
api_response = requests.get(
'https://api.tripleseat.com/api/v1/locations',
headers={'Authorization': f'Bearer {access_token}'}
)JavaScript/Node.js
OAuth 1.0 (Old)
const OAuth = require('oauth');
const oauth = new OAuth.OAuth(
'https://api.tripleseat.com/oauth/request_token',
'https://api.tripleseat.com/oauth/access_token',
CONSUMER_KEY,
CONSUMER_SECRET,
'1.0',
null,
'HMAC-SHA1'
);
oauth.get(
'https://api.tripleseat.com/api/v1/locations',
TOKEN,
TOKEN_SECRET,
(error, data) => {
console.log(data);
}
);OAuth 2.0 (New)
const axios = require('axios');
// Step 1: Generate authorization URL (redirect user here)
const authorizationUrl = `https://login.tripleseat.com/oauth2/authorize?` +
`client_id=${CLIENT_ID}&` +
`redirect_uri=${encodeURIComponent(REDIRECT_URI)}&` +
`response_type=code&` +
`scope=read+write`;
// Redirect user to authorizationUrl...
// After user authorizes, you'll receive the authorizationCode
// Step 2: Exchange authorization code for token
const tokenResponse = await axios.post(
'https://api.tripleseat.com/oauth2/token',
new URLSearchParams({
grant_type: 'authorization_code',
code: authorizationCode,
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
redirect_uri: REDIRECT_URI
}),
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}
);
const { access_token, refresh_token } = tokenResponse.data;
// Step 3: Make API request
const apiResponse = await axios.get(
'https://api.tripleseat.com/api/v1/locations',
{
headers: {
'Authorization': `Bearer ${access_token}`
}
}
);
// Step 4: Refresh token
const refreshResponse = await axios.post(
'https://api.tripleseat.com/oauth2/token',
new URLSearchParams({
grant_type: 'refresh_token',
refresh_token: refresh_token,
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET
}),
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}
);OAuth 1.0 Exchange (Migration)
const axios = require('axios');
// Exchange existing OAuth 1.0 credentials for OAuth 2.0 tokens
const tokenResponse = await axios.post(
'https://api.tripleseat.com/oauth2/token',
new URLSearchParams({
grant_type: 'oauth1_exchange',
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
consumer_key: CUSTOMER_OAUTH1_CONSUMER_KEY,
consumer_secret: CUSTOMER_OAUTH1_CONSUMER_SECRET
}),
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}
);
const { access_token, refresh_token } = tokenResponse.data;
// Make API request
const apiResponse = await axios.get(
'https://api.tripleseat.com/api/v1/locations',
{
headers: {
'Authorization': `Bearer ${access_token}`
}
}
);PHP
OAuth 1.0 (Old)
$oauth = new OAuth(
CONSUMER_KEY,
CONSUMER_SECRET,
OAUTH_SIG_METHOD_HMACSHA1,
OAUTH_AUTH_TYPE_AUTHORIZATION
);
$oauth->setToken(TOKEN, TOKEN_SECRET);
$oauth->fetch('https://api.tripleseat.com/api/v1/locations');
$response = $oauth->getLastResponse();OAuth 2.0 (New)
// Step 1: Generate authorization URL (redirect user here)
$authorizationUrl = 'https://login.tripleseat.com/oauth2/authorize?' . http_build_query([
'client_id' => CLIENT_ID,
'redirect_uri' => REDIRECT_URI,
'response_type' => 'code',
'scope' => 'read write'
]);
// Redirect user to $authorizationUrl...
// After user authorizes, you'll receive the $authorizationCode
// Step 2: Exchange authorization code for token
$ch = curl_init('https://api.tripleseat.com/oauth2/token');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
'grant_type' => 'authorization_code',
'code' => $authorizationCode,
'client_id' => CLIENT_ID,
'client_secret' => CLIENT_SECRET,
'redirect_uri' => REDIRECT_URI
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/x-www-form-urlencoded'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
$accessToken = $response['access_token'];
$refreshToken = $response['refresh_token'];
// Step 3: Make API request
$ch = curl_init('https://api.tripleseat.com/api/v1/locations');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $accessToken
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$apiResponse = curl_exec($ch);
curl_close($ch);
// Step 4: Refresh token
$ch = curl_init('https://api.tripleseat.com/oauth2/token');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
'grant_type' => 'refresh_token',
'refresh_token' => $refreshToken,
'client_id' => CLIENT_ID,
'client_secret' => CLIENT_SECRET
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/x-www-form-urlencoded'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$newToken = json_decode(curl_exec($ch), true);
curl_close($ch);OAuth 1.0 Exchange (Migration)
// Exchange existing OAuth 1.0 credentials for OAuth 2.0 tokens
$ch = curl_init('https://api.tripleseat.com/oauth2/token');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
'grant_type' => 'oauth1_exchange',
'client_id' => CLIENT_ID,
'client_secret' => CLIENT_SECRET,
'consumer_key' => CUSTOMER_OAUTH1_CONSUMER_KEY,
'consumer_secret' => CUSTOMER_OAUTH1_CONSUMER_SECRET
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/x-www-form-urlencoded'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
$accessToken = $response['access_token'];
$refreshToken = $response['refresh_token'];
// Make API request
$ch = curl_init('https://api.tripleseat.com/api/v1/locations');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $accessToken
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$apiResponse = curl_exec($ch);
curl_close($ch);Testing Your Migration
1. Development Environment Testing
- Create a new OAuth 2.0 application in your development environment
- Test the complete authentication flow
- Verify all API endpoints work with the new Bearer token
- Test token refresh mechanism
2. Parallel Testing
- Run both OAuth 1.0 and OAuth 2.0 implementations side by side
- Compare responses to ensure consistency
- Monitor for any performance differences
3. Staging Environment Validation
- Deploy OAuth 2.0 implementation to staging
- Perform full integration testing
- Test error handling and edge cases
Troubleshooting
Common Issues and Solutions
“invalid_grant” Error
Problem: Authorization code or refresh token is invalid
Solution: - Ensure redirect URI matches exactly between app configuration and requests - Verify authorization code is used within 10 minutes - Check that refresh token hasn’t been revoked
“401 Unauthorized” Error
Problem: Access token is expired or invalid
Solution: - Implement automatic token refresh using refresh_token - Ensure Bearer token format is correct: Authorization: Bearer TOKEN - Verify token hasn’t been manually revoked
“invalid_client” Error
Problem: Client credentials are incorrect
Solution: - Double-check client_id and client_secret - Ensure credentials are from OAuth 2.0 app, not OAuth 1.0 - Verify credentials haven’t been regenerated
Rate Limiting Issues
Problem: Hitting API rate limits
Solution: - OAuth 2.0 uses the same rate limits as OAuth 1.0 - Implement exponential backoff for retries - Cache responses when appropriate
Token Expiration Handling
Problem: Access tokens expire after 2 hours
Solution:
// Example token refresh logic
async function makeApiRequest(url) {
try {
return await fetch(url, {
headers: { 'Authorization': `Bearer ${accessToken}` }
});
} catch (error) {
if (error.status === 401) {
// Refresh the token
const newTokens = await refreshAccessToken();
accessToken = newTokens.access_token;
// Retry the request
return await fetch(url, {
headers: { 'Authorization': `Bearer ${accessToken}` }
});
}
throw error;
}
}
Migration Checklist
- Created OAuth 2.0 application in Tripleseat
- Obtained new client_id and client_secret
- Updated authentication flow to use OAuth 2.0
- Replaced signature-based auth with Bearer tokens
- Implemented token refresh mechanism
- Updated all API request headers
- Tested in development environment
- Validated in staging environment
- Monitored for any API response differences
- Updated error handling for OAuth 2.0 responses
- Documented new credentials securely
- Planned production deployment
Support Resources
Documentation
Getting Help
- Technical Support or Integration questions: Contact Support
- Emergency Migration Assistance: Available for enterprise customers
Important Dates
- Early Bird Migration (Before January 1, 2026): Priority support available
- Final Migration Deadline: June 30, 2026
- OAuth 1.0 Complete Shutdown: July 1, 2026
Frequently Asked Questions
Q: Do all my customers need to create an OAuth 2.0 application in their accounts as part of the migration?
A: For Partners integrating many customers, only the partner needs to create a single OAuth 2.0 application in their sandbox account that each customer authorizes against, usually via a "Connect to Tripleseat" button in their account. They then store their access and refresh tokens in order to query the API on their behalf.
Q: Can I use both OAuth 1.0 and OAuth 2.0 simultaneously during migration?
A: Yes, both authentication methods will work in parallel until June 30, 2026.
Q: Will my existing OAuth 1.0 tokens stop working immediately on June 30, 2026?
A: Yes, all OAuth 1.0 authentication will be rejected after the sunset date.
Q: Do OAuth 2.0 rate limits differ from OAuth 1.0?
A: No, the same rate limits apply regardless of authentication method.
Q: Can I migrate my existing OAuth 1.0 tokens to OAuth 2.0?
A: Yes. If you have a customer's existing OAuth 1.0 Consumer Key and Consumer Secret, you can exchange them for OAuth 2.0 tokens using the oauth1_exchange grant type with no customer action required. See the "Migrating Customers with Existing OAuth 1.0 Credentials" section above for details. Alternatively, customers can authorize your OAuth 2.0 application through the standard authorization flow.
Q: What happens if I don’t migrate by June 30, 2026?
A: Your integration will lose API access. Emergency extensions may be available for enterprise customers on
a case-by-case basis.
Q: Are there any API endpoint changes with OAuth 2.0?
A: No, only the authentication method changes. All /api/v1/* endpoints remain the same.
Q: How do I onboard customers with OAuth 2.0? Will customers still need to provide me with their specific credentials?
A: No, the only credentials you now need are your single set of OAuth 2.0 credentials. You provide your customer with a "Connect to Tripleseat" button, and once they authenticate in the Tripleseat portal, they are redirected back to your app with the required tokens (auth and refresh). You need to store these tokens for use with the API against the customer's data in Tripleseat.
Conclusion
Migrating from OAuth 1.0 to OAuth 2.0 will simplify your integration while improving security and maintainability. Start your migration early to ensure a smooth transition before the June 30, 2026 deadline.
For additional assistance or questions not covered in this guide, please contact Support.