Reference
Errors

Error Handling

When a request fails, the API returns an appropriate HTTP status code and a JSON body with error details.


Example error response

{
  "error": "Unauthorized",
  "message": "Invalid or missing API key",
  "code": "INVALID_API_KEY"
}

Some responses include a code field for programmatic handling. When the error is scope-related, you'll also see required (the scope name).


Error codes reference

CodeHTTPDescription
INVALID_API_KEY / UNAUTHORIZED401API key or Bearer token is missing, invalid, or expired
missing_scope403Token does not have the required scope; check required in the body
FILE_TOO_LARGE413Uploaded file exceeds the allowed size for your plan
RATE_LIMIT429Too many requests; use retryAfter or Retry-After to retry later
2fa_required400TOTP code required (e.g. when generating/revoking tokens with 2FA enabled)
2fa_invalid400TOTP code missing or incorrect

By HTTP status

StatusWhen
200 / 201Success
400Bad request (validation, invalid body). For 2FA: code: 2fa_required or 2fa_invalid
401Missing or invalid authentication (INVALID_API_KEY, UNAUTHORIZED)
403Forbidden: plan limit, disabled account, or token without required scope (code: missing_scope, required)
404Resource not found (e.g. CID not found for pin/delete)
409Conflict (e.g. duplicate token name)
413Payload too large (FILE_TOO_LARGE)
429Rate limit exceeded (RATE_LIMIT); see Rate limits
500 / 503Server or dependency error

Handling errors in code

JavaScript (fetch)

const res = await fetch('https://api.pinarkive.com/api/v3/files', {
  method: 'POST',
  headers: { 'X-API-Key': API_KEY },
  body: formData,
});
 
if (!res.ok) {
  const err = await res.json();
  if (res.status === 403 && err.code === 'missing_scope') {
    console.error('Missing scope:', err.required);
  }
  if (res.status === 429) {
    const retryAfter = res.headers.get('Retry-After') || err.retryAfter;
    console.error('Rate limited. Retry after', retryAfter, 'seconds');
  }
  throw new Error(err.message || res.statusText);
}

JavaScript (axios)

try {
  await axios.post('https://api.pinarkive.com/api/v3/files', formData, {
    headers: { 'X-API-Key': API_KEY },
  });
} catch (e) {
  if (e.response?.status === 429) {
    const retryAfter = e.response.headers['retry-after'] ?? e.response.data?.retryAfter;
    console.error('Rate limited. Retry after', retryAfter, 'seconds');
  }
  if (e.response?.data?.code === 'missing_scope') {
    console.error('Missing scope:', e.response.data.required);
  }
}

Next steps