Learn how to handle API errors and webhook failures in your application
This guide shows you how to handle errors from the Chirp API in your application. For a full reference of the error format, see Errors. For details on specific error codes, see Error Codes.
Every error response from the Chirp API has the same structure. Start by checking the error.type field to determine the category of the problem.
Copy
const response = await fetch("https://api.buildwithchirp.com/v1/sms", { method: "POST", headers: { "Authorization": `Bearer ${apiKey}`, "Content-Type": "application/json", }, body: JSON.stringify({ from: "+15551234567", to: ["+15559876543"], text: "Hello from Chirp!", }),});if (!response.ok) { const { error } = await response.json(); switch (error.type) { case "invalid_request_error": // Fix the request and try again console.error(`Bad request: ${error.message}`); break; case "authentication_error": // Check your API key console.error(`Auth failed: ${error.message}`); break; case "provider_error": // The request was valid but the provider rejected it console.error(`Provider error: ${error.message}`); break; case "api_error": // Something went wrong on Chirp's end - retry later console.error(`Server error: ${error.message}`); break; }}
When an error has a provider object, you can access the raw error from Meta or Telnyx for additional debugging context.
Handling provider errors
Copy
if (!response.ok) { const { error } = await response.json(); if (error.provider) { console.error("Provider error details:", { source: error.provider.source, code: error.provider.code, message: error.provider.message, }); // If it's a Meta error, save the trace ID for support if (error.provider.fbtrace_id) { await saveTraceId(messageId, error.provider.fbtrace_id); } }}
When the param field is present, it tells you which request parameter caused the error. Use this to provide targeted feedback in your UI.
Handling validation errors
Copy
if (!response.ok) { const { error } = await response.json(); if (error.type === "invalid_request_error" && error.param) { // Highlight the specific form field that has an error setFieldError(error.param, error.message); }}
Never retry invalid_request_error or authentication_error automatically. These indicate a problem with your request that will not resolve on its own. Retrying will waste your rate limit budget.
Log error details to help your team debug issues in production.
Error logging
Copy
function logApiError(context, error) { const logEntry = { timestamp: new Date().toISOString(), context, error: { type: error.type, code: error.code, message: error.message, param: error.param, }, }; // Include provider details for upstream errors if (error.provider) { logEntry.provider = { source: error.provider.source, code: error.provider.code, message: error.provider.message, }; // fbtrace_id is critical for Meta support tickets if (error.provider.fbtrace_id) { logEntry.provider.fbtrace_id = error.provider.fbtrace_id; } } console.error(JSON.stringify(logEntry));}
When contacting Meta support about a WhatsApp issue, always include the fbtrace_id from the error response. This allows Meta to look up the exact request in their systems.