Upcoming Change — Standardized Error Response Format
In the next release (targeted for approximately mid-July 2026), we're standardizing the error response body across the Preczn API. Most endpoints already return the standard shape shown below — for example, ACH transaction errors follow it today. A set of older endpoints currently return a slightly different shape, and those are being brought in line.
The error messages are not changingOnly the JSON field names change. The human-readable text you receive today is preserved exactly — it simply moves from the
errorfield into themessagefield. HTTP status codes are unchanged too. If your integration only matches on message text or the HTTP status code, no action is needed.
How the error body is changing
Today, the affected endpoints return this legacy shape:
{
"status": 404,
"error": "Merchant not found!"
}After the change, they return our standard shape:
{
"statusCode": 404,
"message": "Merchant not found!",
"error": "Not Found"
}Three things change in the body — and nothing else:
| Legacy field | Standard field | What changed |
|---|---|---|
status | statusCode | Same numeric HTTP code — only the key name changes. |
error (held the message) | message | The human-readable detail now lives in message. It may be a string or, for validation errors, an array of strings. |
| (did not exist) | error (new meaning) | Now holds the short HTTP reason phrase: Bad Request, Forbidden, Not Found, or Unprocessable Entity. It no longer carries the detail message. |
The HTTP response status code (400, 403, 404, 422, …) on the response itself does not change.
What you need to do
Action required only if you read the response body fields
- If you read the numeric code from the body's
statusfield, read it fromstatusCodeinstead (or rely on the HTTP response status, which is unchanged).- If you read the error detail from the
errorfield, read it frommessageinstead.- Stop treating
erroras the detail message — after the change it contains a fixed reason phrase, not the specifics.
If you already consume the standard shape (for example, the format returned by ACH transaction errors), there's nothing to do — these endpoints will now match what you already handle.
Which endpoints are affected
The change applies to validation, permission, and not-found errors on endpoints you call with your Preczn API key:
- Transactions — loan, drawdown, and ACH plan-routing errors (
POST /v1/transactions) - Tokenization — token creation and updates (
POST /v1/tokens,PATCH /v1/tokens/:id) - Merchants — create, update, delete, owners, credentials, and connection onboarding (
POST/PATCH/DELETE /v1/merchants/**) - Boarding form & requirement setup — form creation and lookups (
POST /v1/forms,GET /v1/forms/merchant/:merchantId), form templates (POST/PATCH /v1/formTemplates), and requirement templates (POST/PATCH/GET /v1/requirements) - Plans — platform plan lookups (
GET /v1/plans) - Webhooks — webhook lookups (
GET /v1/webhooks/:id) - Sessions — client session creation (
POST /v1/sessions) - Compliance (SAQ) — SAQ state, signing, draft PDF, and upload errors (
/v1/saq/**)
Two response shapes that omit error
errorA couple of error types use a shorter shape that has no error reason phrase. Read the code from statusCode and the detail from message as usual — just treat error as optional and don't depend on it being present.
File upload errors (e.g. an unsupported file type on a form-template or compliance upload) return only statusCode and message:
{
"statusCode": 400,
"message": "image/jpeg mimetype not supported. Allowed mimetypes: image/png"
}428 Precondition Required (returned when deleting a merchant that still has a loan request) also omits error:
{
"statusCode": 428,
"message": "Can't delete merchant that have Loan Request"
}FAQ
In shortYour integration only needs changes if it reads the
statusorerrorfields out of the error response body. If it keys off the HTTP response status code or matches on the message text, it keeps working unchanged.
Q: Are the error messages themselves changing?
A: No. The wording is identical. The text just moves from the error field into the message field.
Q: Are the HTTP status codes changing?
A: No. A 404 is still a 404. The only thing that moves is the numeric value's location inside the body (status → statusCode); the HTTP response status line is untouched.
Q: My integration checks the body's status field to branch on errors. What should I do?
A: Read statusCode instead. Better still, branch on the HTTP response status code from your HTTP client — that has always been reliable and isn't changing.
Q: My integration reads the message from the error field. What should I do?
A: Read message instead. After the change, error is a fixed reason phrase (e.g. "Bad Request"), not the detailed message.
Q: My integration matches on the error message string. Am I affected?
A: No — the message text is unchanged. We still recommend branching on statusCode rather than message strings, since message wording can change in future releases.
Q: I only check the HTTP response status code, not the body. Am I affected?
A: No. No action needed.
Q: Some responses don't include an error field at all. Is that a bug?
A: No. File-upload errors and the 428 Precondition Required response use a shorter shape with no reason phrase. Always read statusCode and message, and treat error as optional.
Q: When does this take effect, and what if I have concerns?
A: It ships in the next release, targeted for approximately mid-July 2026. If you have concerns about your integration, reach out to your Preczn contact and we'll help you assess the impact.
Recommended handling
Read the code and detail defensively, prefer the HTTP status code, and treat error as optional:
try {
await preczn.merchants.get(merchantId);
} catch (err) {
const status = err.response.status; // HTTP status — most reliable, unchanged
const body = err.response.data;
const code = body.statusCode ?? body.status; // tolerate both during rollout
const detail = body.message ?? body.error; // human-readable detail (string or array)
// ...branch on `status` / `code`, surface `detail`
}The ?? body.status / ?? body.error fallbacks let the same code handle both the legacy and standard shapes, so you can update ahead of the release without timing your deploy to ours.
