Troubleshooting & Security
Troubleshooting
| Symptom | Cause / fix |
|---|---|
401 Invalid or missing API key |
Key missing, mistyped, revoked, or in the wrong header. It must be X-API-Key. |
403 not enabled for language tests |
The organization doesn't have language tests enabled. A platform admin must enable it before provisioning. |
400 Unknown course type '…' |
Use an exact value from GET /courses/ (e.g. pte_academic, not pte). Only active course types are accepted. |
400 'email'/'first_name'/'courses' is required |
A required field is empty or not mapped from the trigger. |
| Student not in the course | Confirm the response enrollments[] lists the course. If it does but the student still can't see it, ask your platform administrator to check the audit log for that email. |
| Student didn't get the email | Check welcome_email_sent in the response; you can always resend using set_password_url, or send your own email with send_welcome_email: false. |
| A returning student isn't getting access | If their enrollment is suspended, provisioning leaves it untouched (skipped_reason: suspended). Lift the suspension in the admin. |
| Duplicate calls | Harmless — the API is idempotent; a repeat returns already_provisioned. |
Provisioning logs
Every call made with an API key — success, failure, or an invalid/revoked-key 401 — is recorded
in a server-side audit log (email, courses, result, source, IP, time). Your platform
administrator can look this up (Provisioning Logs) — it's the first place to check when a call "didn't
work" but the request looked correct. (Anonymous probes with no key at all are not persisted.)
Security
- Always call over HTTPS.
- Treat the API key like a password. Use a separate key per automation tool so you can revoke one without affecting the others.
- Rotate keys periodically: create a new key, switch your automation to it, then revoke the old one.
- The key scopes access to your organization only — it cannot read or write any other organization's data.
- Only a SHA-256 hash of each key is stored; the raw key is shown once at creation and never again.
- Secret-looking fields in a request payload (anything containing
password,secret,token,api_key,credential, …) are masked before the payload is written to the audit log.
