Troubleshooting
Find the symptom, then read the cause and the fix.
Requests fail
Section titled “Requests fail”Every error body has a code. The Error codes table lists them all.
| Symptom | Cause | Fix |
|---|---|---|
401 API key is required |
The X-API-Key header is missing. |
Send the header on every /api/* request. |
401 Invalid API key |
The key is wrong, has extra spaces, or was regenerated in the dashboard. | Copy the current key from System → Developers → API Key. |
400 property maxAttempts should not exist (or another field) |
You sent a schedule setting to Create a campaign. | Create accepts only agentId, name and recipients. Send schedule settings to Start a campaign. |
400 Recipient validation failed |
One or more recipients don’t match the agent’s paramsSchema. Nothing was created. |
Read errors: each line names the row and the field. See paramsSchema. |
409 CAMPAIGN_NAME_TAKEN |
Campaign names must be unique in your organization. | Add a date or batch number to the name. |
409 Campaign has already been started… |
You called Start on a campaign that isn’t DRAFT. |
A campaign can be started once. Create a new campaign to call people again. |
403 Your organization is not allowed to make calls. |
Calling is turned off for your organization. | Contact Gowajee. |
400 Unknown caller ID: … |
A number in callerIds isn’t one of your numbers, or is written differently. |
Copy it exactly as shown in System → Settings → Phone Numbers. |
400 Unknown voice: … |
A key in ttsVoiceKeys is misspelled or retired. |
Use a voiceKey from the voice catalog. |
404 CAMPAIGN_NOT_FOUND, CALL_NOT_FOUND… |
The ID doesn’t exist, or it belongs to another organization. | Check the ID, and that you use the right API key. |
400 INVALID_ID |
An ID in the path isn’t a UUID, for example a campaign name or an empty string. | Send the id exactly as the API returned it. |
409 INVALID_CAMPAIGN_STATE |
Pause, resume or cancel isn’t allowed from the campaign’s current status. | See State rules. |
400 timeWindows.0.time.0.start must be HH:MM… |
An hour has one digit, for example 9:00. |
Always use two digits: 09:00. |
A campaign doesn’t call anyone
Section titled “A campaign doesn’t call anyone”Check these in order:
- Status. Is it still
DRAFT? Creating a campaign doesn’t start it. Call Start. - Start time.
startDateTimeis UTC.2026-10-01T09:00:00Zis 16:00 in Bangkok, not 09:00. - Calling hours. Is right now inside
timeWindowsin Bangkok time? Days you didn’t list get no calls. - Deadline. If
endDateTimehas passed, the campaign isEXPIRED. - Paused. A
PAUSEDcampaign waits until you resume it.
The scheduler runs about every 30 seconds, so allow a minute after the start time.
Retries behave strangely
Section titled “Retries behave strangely”| Symptom | Cause | Fix |
|---|---|---|
400 retryInterval must be at least 300000 ms (5 minutes)… |
retryInterval is in milliseconds, and the minimum is 5 minutes when retries are on. 2 means 2 ms. |
2 hours = 7200000. Or leave it out to get 1 hour. See Retries. |
| No retries at all | maxAttempts defaults to 1 (one call, no retry). |
Send maxAttempts: 3 for the first call plus 2 retries. |
| A retry comes the next morning | The retry became due outside the calling hours. | Working as designed. It waits for the next window. |
| Someone is never retried | They were reached once (COMPLETED, including voicemail). |
Working as designed. |
| Retries stopped | The campaign is PAUSED. |
Resume it. Retries that are due continue. |
Someone was called again with maxAttempts: 1 |
Their call ended as CANCELLED after waiting too long in the queue. That doesn’t use up an attempt. |
Working as designed. |
Webhook problems
Section titled “Webhook problems”| Symptom | Cause | Fix |
|---|---|---|
| Nothing arrives | No webhook URL is saved, or the URL can’t be reached from the internet. | Set it in System → Developers → Webhook URL. It must be public. Use HTTPS. |
Nothing arrives, and your URL redirects (for example http:// to https://) |
Redirects are not followed. A 3xx counts as a failure. |
Save the final URL, exactly as your server expects it (scheme, host, path and trailing /). |
| Some results never arrive | Your server was down or slow. Gowajee tries 3 times (waiting 1 s, then 2 s), with a 10-second timeout each, then stops. | Reply 2xx fast and process later. Back it up with polling. |
| No webhook for some calls | EXPIRED calls, calls stopped by a campaign cancel, ANALYSIS_FAILED calls, and COMPLETED calls that weren’t analyzed (no recording or transcript, or the agent stopped with an error) send no webhook. |
Read them with polling. See When is it sent? |
| The same call arrives twice | A retry of the delivery, or a re-analysis (isReAnalysis: true). |
Upsert on call.id. |
callDuration breaks your parser |
It is a string, e.g. "120.120". |
Parse it with parseFloat / float(). |
Recordings and data
Section titled “Recordings and data”| Symptom | Cause | Fix |
|---|---|---|
The recording link returns 403 from storage |
Recording links expire within 1 hour. | Get a new link from /record-url each time you need one. |
404 RECORDING_NOT_FOUND |
The call never connected (NO_ANSWER, BUSY…) or is still in progress. |
Only connected calls have audio. |
410 RECORDING_DELETED |
The data-retention policy deleted the recording, or its campaign was deleted. | It can’t be restored. Save recordings you need to keep. |
tel looks like 08xxxxxx78 and names are empty |
Your organization’s data-retention policy removed personal data. | Check dataExpired on calls and webhooks, or personalDataMasked on recipients. Keep your own copy if you need it longer. |
Leading 0 missing from phone numbers |
tel was sent as a JSON number. |
Always send tel as a string: "0812345678". |
| Times look 7 hours off | API timestamps are UTC. | Convert to Bangkok time (UTC+7) for display. |
Still stuck? Send Gowajee support the campaign ID, the call ID or sessionId, and the exact request and response.