Skip to main content

Error Handling

The API uses standard HTTP status codes and returns consistent JSON error bodies for all failure cases.

HTTP status codes

CodeMeaningCommon cause
200OKRequest succeeded
201CreatedResource was created
204No ContentResource was deleted
400Bad RequestMalformed request body
401UnauthorizedMissing or invalid Authorization header
403ForbiddenToken valid but insufficient permissions
404Not FoundResource does not exist or belongs to another tenant
422Unprocessable EntityValidation failed (see errors field)
429Too Many RequestsRate limit exceeded
500Internal Server ErrorUnexpected server error

Error response body

All error responses return a JSON body. The structure varies by error type.

Validation error (422)

{
  "message": "The given data was invalid.",
  "errors": {
    "email": ["The email field is required.", "The email must be a valid email address."],
    "course_uuid": ["The selected course uuid is invalid."]
  }
}
The errors object maps field names to an array of human-readable messages.

Authentication error (401)

{
  "message": "Unauthenticated."
}

Not found (404)

{
  "message": "No query results for model [App\\Certificate] 550e8400-e29b-41d4-a716-446655440000"
}

Generic server error (500)

{
  "message": "Server Error"
}

Handling errors in code

async function createCertificate(payload) {
  const response = await fetch('https://api.dokstamp.eu/certificates', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${TOKEN}`,
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-Tenant': TENANT,
    },
    body: JSON.stringify(payload),
  });

  if (!response.ok) {
    const error = await response.json();

    if (response.status === 422) {
      // Validation error — inspect error.errors for field-level detail
      console.error('Validation failed:', error.errors);
    } else if (response.status === 401) {
      // Token expired or missing — refresh and retry
      await refreshToken();
    } else {
      throw new Error(error.message);
    }
  }

  return response.json();
}

Common mistakes

Returns 401 or 404 depending on the endpoint. Always include X-Tenant on resource endpoints.
When creating a certificate, the file_uuid must reference a file that has not yet been attached to another certificate. Files track a used_at timestamp — once set, the file cannot be reused.
All UUID fields must be in standard v4 format: 550e8400-e29b-41d4-a716-446655440000. Passing an integer ID where a UUID is expected returns 422.
If you pass a course_uuid or student_uuid that belongs to a different tenant, the API returns 422 with "The selected ... is invalid." — the entity lookup is always tenant-scoped.