Troubleshooting
Error reference and debugging guide for the Connected Accounts API — authentication, rate limiting, OAuth flows, integrations, and common issues.
Troubleshooting
This page covers every error you might encounter when using the Connected Accounts API, organized by category. Each error includes the HTTP status code, response format, common causes, and how to fix it.
Authentication Errors
401 — Invalid or Missing API Key
{
"ok": false,
"error": "Invalid or missing API key"
}Causes:
- Missing
Authorizationheader - Malformed header (must be
Bearer sk_live_...) - API key was deleted or regenerated in the dashboard
- Using a key from a different environment
Fix: Verify the header format is exactly Authorization: Bearer sk_live_your_key_here. If the key was regenerated, update your application with the new key.
403 — Partner Required
{
"ok": false,
"error": "Partner profile required",
"error_code": "PARTNER_REQUIRED"
}Causes:
- The API key belongs to an account that hasn't registered as a partner
- Partner profile was deactivated
Fix: Register as a partner at supyagent.com/settings/partner. See the Quickstart.
403 — Partner Suspended
{
"ok": false,
"error": "Partner profile is suspended"
}Causes:
- Partner profile was suspended due to policy violation or billing issue
Fix: Contact support to resolve the suspension.
401 — Payment Past Due
{
"ok": false,
"error": "Payment past due. Please update your payment method."
}Causes:
- Stripe payment failed and subscription status is
past_due - Applies to all tiers — all API requests are blocked until resolved
Fix: Update your payment method in the dashboard at Settings > Billing. API access resumes immediately after successful payment.
Rate Limiting
429 — Rate Limit Exceeded
{
"ok": false,
"error": "Rate limit exceeded"
}The response includes these headers:
| Header | Example | Description |
|---|---|---|
X-RateLimit-Minute-Limit | 30 | Per-minute limit for your tier |
X-RateLimit-Minute-Remaining | 0 | Requests remaining in the current minute |
Retry-After | 45 | Seconds to wait before retrying |
Per-minute limits by tier:
| Tier | Requests/Minute |
|---|---|
| Free | 30 |
| Pro | 300 |
| Enterprise | 1,000 |
Fix: Wait for the Retry-After duration, then retry. Implement exponential backoff in your client. If you consistently hit limits, upgrade your tier.
429 — Monthly Quota Exceeded (Free Tier)
{
"ok": false,
"error": "Free tier limit of 1000 API calls reached. Upgrade to Pro for more."
}The response includes:
| Header | Example | Description |
|---|---|---|
X-RateLimit-Limit | 1000 | Monthly quota |
X-RateLimit-Remaining | 0 | Remaining calls this month |
Causes:
- Free tier has a hard cap of 1,000 API calls per month
- No overage is allowed on the free tier
Fix: Upgrade to Pro at Settings > Billing. Pro tier allows 100,000 calls/month with overage billing at $0.50/1,000 calls.
OAuth Flow Errors
These errors appear as query parameters on your redirect_url after an OAuth flow fails.
access_denied
https://yourapp.com/callback?error=access_deniedCause: The user clicked "Deny" or "Cancel" on the OAuth consent screen.
Fix: Show the user a friendly message explaining why the permission is needed. Offer to retry the connection.
session_expired
https://yourapp.com/callback?error=session_expiredCause: The connect session exceeded its 30-minute time limit. The user took too long to complete authorization.
Fix: Create a new connect session and redirect the user again. Sessions expire 30 minutes after creation.
session_already_used
https://yourapp.com/callback?error=session_already_usedCause: The connect session was already completed (the authorization code was already exchanged). This can happen if the user refreshes the callback page or navigates back.
Fix: Check the session status — the integration may already be active. If not, create a new connect session.
no_code
https://yourapp.com/callback?error=no_codeCause: The OAuth provider redirected back without an authorization code. This is unusual and typically indicates a provider-side issue.
Fix: Retry the connection. If it persists, check the provider's status page.
token_exchange_failed
https://yourapp.com/callback?error=token_exchange_failedCause: Supyagent received the authorization code but failed to exchange it for tokens. This can happen if:
- The OAuth app credentials are misconfigured
- The provider's token endpoint is down
- The PKCE code verifier doesn't match
Fix: Retry the connection. If it persists, verify your OAuth app is correctly configured with the provider.
Integration Errors
Account Not Found
{
"ok": false,
"error": "Connected account \"invalid-id\" not found"
}Causes:
- The
X-Account-Idvalue doesn't match anyexternal_idunder your partner profile - Typo in the
external_id - The account was deleted
Fix: Verify the external_id matches exactly. Use List Accounts to see all accounts.
Integration Not Found
{
"ok": false,
"error": "No active google integration for this account",
"error_code": "INTEGRATION_NOT_FOUND"
}Causes:
- The account doesn't have the requested provider connected
- The integration was disconnected
- The integration status is
expiredorrevoked
Fix: Check the account's integrations, then initiate a new connect session if needed.
Token Error
{
"ok": false,
"error": "Failed to refresh access token",
"error_code": "INTEGRATION_TOKEN_ERROR"
}Causes:
- The refresh token is invalid (user revoked access from the provider's settings)
- The provider's token endpoint returned an error
- The OAuth app's credentials changed
Fix: The user needs to re-authorize. Create a new connect session for the provider. The old integration will be replaced.
Duplicate External ID
{
"ok": false,
"error": "Account with external_id \"user-123\" already exists",
"error_code": "DUPLICATE_EXTERNAL_ID"
}Cause: You tried to create an account with an external_id that already exists under your partner profile.
Fix: Use the existing account, or choose a different external_id. Use Get Account to find the existing account.
Debugging Workflow
Step 1: Verify Authentication
# Test your API key
curl -s https://app.supyagent.com/api/v1/accounts?limit=1 \
-H "Authorization: Bearer sk_live_your_key_here" | jq .okExpected: true. If false, check your API key.
Step 2: Verify the Connected Account
# List accounts to find the external_id
curl -s https://app.supyagent.com/api/v1/accounts \
-H "Authorization: Bearer sk_live_your_key_here" | jq '.data.accounts[] | {external_id, id}'Step 3: Verify the Integration
# Check integration status for a specific account
curl -s https://app.supyagent.com/api/v1/accounts/ACCOUNT_UUID/integrations \
-H "Authorization: Bearer sk_live_your_key_here" | jq '.data.integrations[] | {provider, status}'Look for "status": "active". If the status is expired or revoked, the user needs to re-authorize.
Step 4: Test the Provider Call
# Make a simple read-only call
curl -v https://app.supyagent.com/api/v1/google/gmail/messages \
-H "Authorization: Bearer sk_live_your_key_here" \
-H "X-Account-Id: user-123"The -v flag shows response headers including rate limit info.
Step 5: Check Rate Limits
Look at the response headers:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 847
X-RateLimit-Minute-Limit: 30
X-RateLimit-Minute-Remaining: 28If X-RateLimit-Remaining is 0, you've hit your monthly quota. If X-RateLimit-Minute-Remaining is 0, wait for the minute window to reset.
Common Mistakes
| Mistake | Fix |
|---|---|
Using the Supyagent UUID as X-Account-Id | Use the external_id you set when creating the account |
Passing account_id as a query parameter | Use the X-Account-Id header instead |
| Not checking integration status before calling | Check that the integration is active first |
| Creating duplicate accounts instead of reusing | Handle the 409 response and reuse the existing account |
| Caching OAuth tokens client-side | Always go through the Supyagent API — it handles token lifecycle |
Testing & Development
Set up a local development environment for the Connected Accounts API — OAuth callback URLs, provider configuration, and testing without a frontend.
React Components
Dashboard React components for partner registration and profile management — PartnerForm, PartnerRegistration, and PartnerProfileView.