Skip to main content

Connecting accounts

The client_id doesn’t match your workspace’s (copy it from Auth in the dashboard), or integration_id doesn’t match an integration’s identifier. Identifiers are case-sensitive. Also check you’re using the client ID from the same workspace as the integration.
The redirect_uri must match an entry under Auth → Redirect URIs exactly: scheme (http vs https), host, port, path and trailing slash all count.
That’s the provider’s check, not BundleUp’s. Your OAuth app at the provider must list https://auth.bundleup.io/callback as a callback or redirect URL.
The provider rejected the token exchange. Usually the client ID or secret on the integration is wrong, or the secret was regenerated at the provider without updating BundleUp.
The code is more than 5 minutes old, was already exchanged, the redirect_uri in the exchange isn’t exactly the one used to start the flow, or the API key is from a different workspace. Codes are single use: a page refresh that re-runs your callback will fail the second time.
A flow has to be completed within 10 minutes of starting. Send the user through it again.

Making requests

The Authorization header is missing or the API key is wrong. It must be Bearer YOUR_API_KEY. If you rotated the key, the old value stopped working immediately.
The connection ID is missing, has a typo, was deleted, or belongs to a different workspace than the API key. A common cause is using a development connection ID with a production key.
The access token expired and couldn’t be refreshed. If it happens once, retry later. If it keeps happening, the user has probably revoked access; ask them to reconnect. See Connection lifecycle.
Check the path against the provider’s base URL (shown on its page at bundleup.io/integrations). If the base already contains a segment like /api or /v4, don’t repeat it in your path.
Usually a missing scope. Add it to the integration, then have the user reconnect: existing connections don’t gain new scopes. See Choosing scopes.
The connection made more than 100 requests in 60 seconds. Wait 60 seconds and spread your requests out. See Rate limits.
The provider didn’t answer within 20 seconds (10 seconds on retries). For large exports, use paginated or asynchronous endpoints.
By design. Only GET, HEAD and OPTIONS are retried. See Retries.
The connection’s provider doesn’t support that endpoint. Each provider’s page at bundleup.io/integrations lists its Unified API endpoints. Use the Proxy for anything else.

MCP

The provider doesn’t run an MCP server BundleUp can use. Use the Proxy, or give your agent your own tools that call it.
mcp.bundleup.io uses static credentials, not OAuth discovery. Use a client that lets you set headers or a single bearer token, or bridge with mcp-remote. See Using MCP clients.
The provider shows tools based on the connection’s scopes. Add scopes to the integration and have the user reconnect.
Tool names come from providers and aren’t prefixed. Give each server a distinct label (model-hosted MCP) or prefix tool names yourself. See Agents for many users.

Webhooks

Hash the raw body, not re-serialized JSON, and use that webhook’s own signing secret. See Verifying signatures.
Deliveries are attempted once, with a 3-second timeout, and not resent. Respond quickly and reconcile periodically with GET /v1/connections.

FAQ

No. You always bring your own OAuth app credentials for each provider. That keeps your brand on the consent screen and your app’s limits and approvals separate from anyone else’s.
Yes. Create connections from tokens you already hold with POST /v1/connections, passing the integration ID, access token, and optionally the refresh token, expiry and external ID. Use the same OAuth app in the integration as the one that issued the tokens.
BundleUp stores the encrypted tokens and connection metadata. It doesn’t store request or response bodies. See Security.
No. You pay for requests. See Pricing.
See bundleup.io/integrations, which also shows Unified API and MCP support for each.