Parselv1.0.0

Errors

Status codes the Parsel API returns and how to handle them.

The Parsel API uses standard HTTP status codes. All error responses share one body shape, so client code can branch on errors.status regardless of which endpoint produced the error.

Status codes

StatusMeaningWhen you'll see it
200 OKSuccessThe request was authenticated, the resource exists, and the body contains the data.
400 Bad RequestValidation errorThe request body or parameters failed validation. Returned by endpoints that accept input.
401 UnauthorizedMissing or invalid tokenThe Authorization header is absent, malformed, or carries a token that has been revoked or expired. Applies to every authenticated endpoint.
403 ForbiddenMissing required scopeThe token is valid but isn't authorized for the scope this endpoint requires. Every endpoint in the public API enforces one — see Scopes.
404 Not FoundResource not visibleThe resource ID does not exist, or it exists but belongs to a different account. The two cases are not distinguished — both return 404.
422 Unprocessable EntityBusiness-rule rejectionThe request was syntactically valid but rejected by a business rule (for example, an invoice in the wrong state for the requested action).

Every endpoint can return 401 or 403 — those come from token validation, which runs before any endpoint-specific logic. Endpoints that accept request bodies may additionally return 400 or 422.

Error body shape

All non-2xx responses share this shape:

{
  "errors": {
    "message": "The requested resource could not be found",
    "status": "Not Found"
  }
}

Branch on errors.status for programmatic handling, or display errors.message to a human.

401 responses are produced by the auth middleware before reaching any controller. Treat any 401 as "stop and refresh credentials" — see Authentication.

403 responses carry one additional field, errors.required_scope, naming the scope your token is missing:

{
  "errors": {
    "message": "This action requires the WRITE_SHIPMENTS scope",
    "required_scope": "WRITE_SHIPMENTS",
    "status": "Forbidden"
  }
}

Treat 403 as "this token can't do that" rather than retrying — either request a token with the missing scope, or check that you're calling the endpoint you meant to. See Scopes for which scope each endpoint needs.

Suggested handling

async function callParsel(url: string, init?: RequestInit) {
  const res = await fetch(url, {
    ...init,
    headers: {
      Authorization: `Bearer ${process.env.PARSEL_TOKEN}`,
      ...(init?.headers ?? {}),
    },
  });

  switch (res.status) {
    case 200:
      return res.json();
    case 401:
      throw new Error("Parsel token rejected — refresh credentials");
    case 403: {
      const body = await res.json();
      throw new Error(`Parsel token missing scope: ${body.errors?.required_scope}`);
    }
    case 404:
      return null; // not found, or not yours — same response either way
    case 400:
    case 422: {
      const body = await res.json();
      throw new Error(`Parsel rejected request: ${body.errors?.message}`);
    }
    default:
      throw new Error(`Unexpected Parsel response: ${res.status}`);
  }
}
def call_parsel(url, **kwargs):
    resp = requests.get(
        url,
        headers={"Authorization": f"Bearer {os.environ['PARSEL_TOKEN']}"},
        **kwargs,
    )
    if resp.status_code == 200:
        return resp.json()
    if resp.status_code == 401:
        raise RuntimeError("Parsel token rejected — refresh credentials")
    if resp.status_code == 403:
        body = resp.json()
        raise RuntimeError(f"Parsel token missing scope: {body.get('errors', {}).get('required_scope')}")
    if resp.status_code == 404:
        return None
    if resp.status_code in (400, 422):
        body = resp.json()
        raise RuntimeError(f"Parsel rejected request: {body.get('errors', {}).get('message')}")
    resp.raise_for_status()

Treat 404 on a known-valid resource ID as "you don't own this resource" rather than "the resource was deleted." Endpoints scope access to the authenticated account.

On this page