Guides

Handling Failed Requests

Error Response Structure

When Pay-i returns an HTTP 4xx status code, the body of the response contains properties that can be used to understand and diagnose the issue.

The statusCode and message properties are always returned in error responses.

xproxy_error and xproxy_result are optional properties and their presence is dependent on the specific error, the endpoint being called, and your integration method. If the Provider returns errors, then these properties are in addition to the error response values the Provider has returned.

Availability of Error Information

The availability of Pay-i's error information (xproxy_error and xproxy_result) varies based on your integration method:

Integration MethodError Response ContainsNotes
@ingest Decorator (Recommended)Original provider error onlyPay-i error information is not accessible. Contact [email protected] if needed.
Manual Ingest API Callxproxy_error + xproxy_result (for limit errors)Error information provided after the fact, when you manually submit telemetry data
Proxy Routing (for Blocking Limits)xproxy_error + xproxy_result (for limit errors)Error information provided in real-time as part of the proxied provider's response

When using Proxy Routing or making Manual Ingest API calls, any limit-related errors will include the xproxy_result object with details about the blocked limits, as shown in the example below.

Example Unsuccessful Request (400)

"statusCode": 400,
"message": "Bad Request",
"xproxy_error": {
  "code": "limit_reached",
  "message": "Insufficient limit for the requested operation",
},
"xproxy_result": {
  "request_id": "40000b9e-0000-7200-b63f-84710c7967bb",
  "request_tags": ["all_used_tags_are_returned_for_confirmation"],
  "resource_id": "42",
  "use_case_id": "2f9e1c5a-7b3d-48f6-a0d9-6e4f2c8b1a3e",
  "limits": {
    "6e6ae496-3239-46b6-5144-08dc8c8ba991": {
      "state": "blocked"
    },
    "07051e47-4051-44e2-5145-08dc8c8ba991": {
      "state": "bocked_external"
    }
  },
  "blocked_limit_ids": [
    "6e6ae496-3239-46b6-5144-08dc8c8ba991"
  ]
}

Response Values

#FieldDescription
1.statusCodeHTTP status code from the REST call.
2.messageHuman readable error message associated with the HTTP status.
3.xproxy_error (optional)Object containing additional information about the error.
3.1codeSee the Error Codes section for more information. These codes be leveraged to programmatically check for and handle specific errors.
3.2messageHuman readable error message associated with the Pay-i related error.
4.xproxy_result (optional)See xproxy_result.

Handling Errors in Provider Python SDKs

Provider SDKs will raise an APIStatusError exception when processing a failed request. These SDKs will raise exceptions independent of Pay-i as a proxy, so it is a good defensive practice to handle these exceptions in your code.

For example, calling messages.create() with an invalid Anthropic key should be in a try/block to handle the exception:

payi_base_url = "https://api.pay-i.com/api/v1/proxy/anthropic/"

payi_headers = {
  "xProxy-Api-Key": YOUR_PAYI_KEY,
  "xProxy-Forward-anthropic-version": "2023-06-01" # Required by Anthropic
}

client = anthropic.Anthropic(
  base_url = payi_base_url,
  auth_token = YOUR_ANTHROPIC_KEY,
  default_headers=payi_headers
)

try:
  message = client.messages.create(
    model="claude-3-5-sonnet-20240620",
    max_tokens=500,
    messages=[{
      "role": "user",
      "content": [{
        "type": "text",
        "text": "Say 'This API call will sometimes result in APIStatusError exceptions.'"
    	}]
    }]
  )
except anthropic.APIStatusError as e:
	response = e.response.json()

The response will contain both Anthropic's type and error properties, along with Pay-i' statusCode, message, xproxy_error properties.

> print(json.dumps(response, indent=4))
"type": "error",
"error": {
  "type": "authentication_error",
  "message": "invalid x-api-key"
},
"xproxy_error": {
  "code": "provider_error",
  "message": "The downstream provider returned an error."
},
"statusCode": 401,
"message": "Unauthorized"