REST API auth
Two headers on every request —
x-client plus x-api-key. Applies to all /v1/... endpoints.SFTP auth
Username + password (or SSH public key) per environment. Applies to all file-based integrations.
Requesting credentials
1
Contact your Tango onboarding lead
Send an email naming your integrating system, the integrations you plan to use (e.g. “AP Inbound + AR Outbound”), and which environments you need (Test always; Production once UAT signs off).Include the system contact (a real person who will receive expiry / rotation notifications), not a shared inbox.
2
Receive credentials separately per environment
You’ll get two pairs — one for Test, one for Production — usually delivered through your tenant’s secrets-sharing channel (1Password, Bitwarden, an encrypted email attachment, etc.):
- REST APIs: an
x-clientidentifier and anx-api-keysecret. - SFTP: an SFTP username and password (or instructions to register a public SSH key).
3
Store credentials in a secret manager
Before you use them anywhere, put each value in a secret manager (AWS Secrets Manager, HashiCorp Vault, Azure Key Vault, 1Password Secrets Automation, etc.). Reference the secret by name in your application config rather than embedding it.Never commit credentials to a Git repository, even in private repos — rotating after an accidental commit is painful and creates a window where the leaked value is still valid.
4
Verify with a noop call
Confirm everything works before you wire it into your real pipeline. Hit the status endpoint with a known-bad A response with
gu_id — you’ll get a clean error rather than an auth failure:"status": "ERROR" and "error": "Invalid gu_id" (or similar) means auth is working. A 401 / 403 means it isn’t — jump to the troubleshooting section.REST API authentication
Every call toapi.tangoanalytics.com (or testapi.tangoanalytics.com) requires two headers:
Both are required on every request — including the polled
/v1/batch/status endpoint. Submission endpoints (PUT/POST/GET) and status endpoints share the same credentials.
x-client is not a secret — it’s an identifier and may appear in logs. x-api-key is a secret and must be treated like a password: secret-managed, rotated, and never logged in plaintext.Example: send an authenticated request
Auth scheme: API key, not OAuth
Tango uses static API keys delivered in headers — there is no token-exchange / refresh flow. If you’re used to OAuth 2.0 client credentials, the simplification is:- No
/oauth/tokenround-trip on each session. - No access-token expiry to handle in code.
- Rotation is human-driven (you request a new key, Tango issues it, you swap and decommission).
SFTP authentication
File-based integrations (AP/AR/GL/PO/CO/Sales file variants) authenticate against an SFTP host:
Two auth modes are supported:
- Username + password
- SSH public key
The simplest setup — Tango provisions a per-client username and password. Use it the same way as any SFTP login:
Path-level access
Your SFTP user is scoped to a specific directory tree. You’ll typically see:/inbound/... or read outside /outbound/... will fail. If you need access to additional paths (for example, a new integration), request it through your onboarding lead.
Environment separation
Test credentials and Production credentials are independent. Re-using one in the other will fail authentication, even if the values look similar — they’re issued from different key pools.
Bind each set of credentials to a distinct secret-manager path so a misconfigured deployment can’t accidentally pull prod credentials in a test environment.
Security best practices
Never commit credentials
Never commit credentials
Add
.env, *.pem, id_rsa, tango_sftp*, and any other credential-bearing files to .gitignore. If you accidentally commit a credential:- Rotate immediately — the value is compromised the moment it’s pushed, even to a private repo.
- Inform Tango via the security contact.
- Use
git filter-repoor similar to scrub history — though rotation is the only thing that actually mitigates the leak.
Rotate keys on a schedule
Rotate keys on a schedule
Set a reminder to rotate API keys every 6–12 months, and immediately whenever:
- An employee with access leaves your organisation.
- You suspect a leak (logs published, repo briefly public, laptop lost).
- A vulnerability scan flags the secret as exposed.
Don't log credentials
Don't log credentials
Configure your HTTP client and logging library to redact the
x-api-key header in all logs (access logs, error logs, structured-event logs, distributed-trace spans). Most frameworks have header-redaction primitives; use them.Common gotchas:curl -vprints headers includingx-api-key. Don’t paste verbose output into tickets or chat.- Some libraries log full request objects on retries / errors. Verify your retry middleware doesn’t print the key.
Use short-lived environment variables, not config files
Use short-lived environment variables, not config files
For CI / cron / container jobs, pass credentials in as environment variables sourced from your secret manager at start time. Avoid writing them to disk; if you must, restrict permissions (
chmod 600) and clean up afterward.Limit access by IP if possible
Limit access by IP if possible
If your Tango tenant supports IP allowlisting (ask onboarding), restrict your API key to the egress IPs of your integration hosts. This is a defence-in-depth layer — a leaked key with allowlist enforcement is harder to abuse.
Troubleshooting
HTTP 403 Forbidden
HTTP 403 Forbidden
Credentials are valid but your client doesn’t have permission for this endpoint. Possible causes:
- You’re calling an integration your client hasn’t been enabled for — e.g. trying AP endpoints when only AR was provisioned.
- You’re hitting Production with Test-scope credentials (or vice versa) and the API enforces strict separation.
- IP allowlisting (if enabled) is rejecting your egress IP.
x-client value and the endpoint you’re calling.HTTP 400 with `status_message` about headers
HTTP 400 with `status_message` about headers
A required header is missing or malformed. Often this is
Content-Type rather than auth — submission endpoints require Content-Type: application/json for JSON bodies.SFTP: `Permission denied (publickey,password)`
SFTP: `Permission denied (publickey,password)`
SSH-key auth: the public key you registered isn’t matching the private key the client is presenting. Check
ssh -i <keyfile> -v ... output for which key the client tried, and confirm with Tango that they registered the corresponding .pub.Password auth: the password is wrong or the username is mistyped. Some clients silently strip whitespace; copy/paste from your secret manager carefully.SFTP: `No such file or directory` writing to /inbound/<x>
SFTP: `No such file or directory` writing to /inbound/<x>
Your SFTP user isn’t scoped for that integration’s directory. Ask Tango onboarding to grant write access to the relevant
/inbound/<integration>/ path.Credential lifecycle
1
Provision
Tango onboarding creates a client identifier and an API key (and SFTP user, if applicable), per environment.
2
Deploy
You load the credentials into your secret manager and deploy your integration. Verify with a noop call.
3
Operate
Run your integration. Don’t touch the credentials in source code — pull them from the secret manager at runtime.
4
Rotate
Periodically (every 6–12 months) or on incident, request a new key. Deploy the new key everywhere, verify, then ask Tango to revoke the old one.
5
Decommission
When an integration is retired, ask Tango to revoke the associated credentials so they can’t be reused. Delete the secret-manager entries.
Next steps
Quickstart
Use the credentials you just set up to send your first request.
Overview
Background on Tango’s integration patterns — REST async, SFTP, and the shared
gu_id polling flow.
