Protocol Buffers
Overview
PSRESTful supports binary Protocol Buffer (protobuf) responses as an alternative to JSON on a subset of read-only endpoints. Protobuf encodes data into a compact binary format that is smaller on the wire and faster to parse than JSON — making it a good fit for high-volume integrations that process large catalogs or poll inventory frequently.
For typical usage (browsing docs, calling a few endpoints, debugging) JSON is the better choice. Protobuf is worth considering when you are:
- Importing large product catalogs across many suppliers where every kilobyte and millisecond adds up
- Polling inventory at high frequency and want to minimize bandwidth and parse time
- Building server-to-server pipelines where human readability is not a concern
How It Works
PSRESTful uses standard HTTP content negotiation:
- Your client sends an
Accept: application/protobufheader with the request - The API serializes the response into the binary protobuf format
- The response is returned with a
Content-Type: application/protobufheader - Your client deserializes the binary payload using the matching proto definition
If no Accept header is sent (or the value is application/json), the response is returned as JSON as usual.
Supported Endpoints
Protobuf responses are only available on the read-only endpoints listed below. All other endpoints return JSON regardless of the Accept header.
| Service | Version | Endpoint Path | Response Message |
|---|---|---|---|
| Inventory | 1.2.1 | /v1.2.1/suppliers/{id}/inventory/ | inventory.v1.GetInventoryLevelsResponse |
| Inventory | 2.0.0 | /v2.0.0/suppliers/{id}/inventory/ | inventory.v2.GetInventoryLevelsResponse |
| Product Data | 1.0.0 | /v1.0.0/suppliers/{id}/products/{productId}/ | product.v1.GetProductResponse |
| Product Data | 2.0.0 | /v2.0.0/suppliers/{id}/products/{productId}/ | product.v2.GetProductResponse |
| Media Content | 1.0.0 | /v1.0.0/suppliers/{id}/media/ | media.v1.GetMediaContentResponse |
| Media Content | 1.1.0 | /v1.1.0/suppliers/{id}/media/ | media.v1.GetMediaContentResponse |
| PPC | 1.0.0 | /v1.0.0/suppliers/{id}/ppc/decoration-colors/ | ppc.v1.GetDecorationColorsResponse |
| PPC | 1.0.0 | /v1.0.0/suppliers/{id}/ppc/fob-points/ | ppc.v1.GetFobPointsResponse |
| PPC | 1.0.0 | /v1.0.0/suppliers/{id}/ppc/available-locations/ | ppc.v1.GetAvailableLocationsResponse |
| PPC | 1.0.0 | /v1.0.0/suppliers/{id}/ppc/available-charges/ | ppc.v1.GetAvailableChargesResponse |
| PPC | 1.0.0 | /v1.0.0/suppliers/{id}/ppc/pricing-and-configuration/ | ppc.v1.GetConfigurationAndPricingResponse |
JSON vs Protobuf Comparison
| Factor | JSON | Protobuf |
|---|---|---|
| Content type | application/json | application/protobuf |
| Human-readable | Yes | No (binary) |
| Payload size | Larger (text with field names) | Smaller (binary with field numbers) |
| Parse speed | Slower | Faster |
| Schema required | No | Yes (proto definitions) |
| Browser support | Native (response.json()) | Requires a protobuf library |
| Endpoint coverage | All endpoints | 11 read-only endpoints |
Example Requests
curl -s \
-H "X-API-Key: your-api-key" \
-H "Accept: application/protobuf" \
-o response.bin \
"https://api.psrestful.com/v2.0.0/suppliers/HIT/inventory/?productId=5989"The response headers will include:
Content-Type: application/protobufDeserializing Responses
Python — using psdomain
The psdomain package ships the compiled proto definitions for every supported service. Install it and use the generated message classes to parse the binary response.
pip install psdomainimport requests
from psdomain.proto.inventory.v2 import GetInventoryLevelsResponse
response = requests.get(
"https://api.psrestful.com/v2.0.0/suppliers/HIT/inventory/",
params={"productId": "5989"},
headers={
"X-API-Key": "your-api-key",
"Accept": "application/protobuf",
},
)
inventory = GetInventoryLevelsResponse()
inventory.ParseFromString(response.content)
for part in inventory.inventory.part_inventory_array:
print(f"{part.part_id}: {part.quantity_available.quantity.value}")JavaScript — using protobufjs
You can load the .proto definition files and decode the binary response with protobufjs.
import protobuf from "protobufjs";
// Load the proto definition (download from psdomain or vendor into your project)
const root = await protobuf.load("inventory_v2.proto");
const ResponseType = root.lookupType(
"inventory.v2.GetInventoryLevelsResponse"
);
const response = await fetch(
"https://api.psrestful.com/v2.0.0/suppliers/HIT/inventory/?productId=5989",
{
headers: {
"X-API-Key": "your-api-key",
"Accept": "application/protobuf",
},
}
);
const buffer = await response.arrayBuffer();
const inventory = ResponseType.decode(new Uint8Array(buffer));
for (const part of inventory.inventory.partInventoryArray) {
console.log(`${part.partId}: ${part.quantityAvailable.quantity.value}`);
}Combining with Compression
Protobuf responses can be compressed just like JSON responses. Send both headers together for the smallest possible payload:
curl -s \
-H "X-API-Key: your-api-key" \
-H "Accept: application/protobuf" \
-H "Accept-Encoding: zstd, br, gzip" \
-o response.bin \
"https://api.psrestful.com/v2.0.0/suppliers/HIT/inventory/?productId=5989"See Compression for more details on supported encoding methods.
Trade-offs
| Factor | JSON | Protobuf |
|---|---|---|
| Ease of use | Simple — parse with built-in methods | Requires proto definitions and a library |
| Debugging | Easy — readable in logs and browsers | Harder — binary requires tooling to inspect |
| Payload size | Larger | Smaller (typically 30–50% reduction) |
| Parse performance | Good | Faster (especially for large responses) |
| Endpoint support | All endpoints | 11 read-only endpoints |
Best Practices
-
Start with JSON, upgrade selectively. Use JSON for development, testing, and low-volume calls. Switch to protobuf only for the specific endpoints where payload size or parse time is a bottleneck.
-
Combine with compression. Protobuf + gzip (or Brotli/Zstandard) gives you the smallest possible transfer size. See Compression.
-
Pin proto definitions to the API version. The proto message schemas correspond to specific PSRESTful API versions. When you upgrade to a new API version, update your
psdomainpackage to match. -
Check the
Content-Typeheader for fallback. If the server cannot produce a protobuf response (unsupported endpoint, server error), it will return JSON instead. Always checkContent-Typebefore deserializing:
if response.headers["Content-Type"] == "application/protobuf":
inventory = GetInventoryLevelsResponse()
inventory.ParseFromString(response.content)
else:
inventory = response.json()Related Documentation
- Compression — HTTP compression with gzip, Brotli, and Zstandard
- Caching — API response caching and cache bypass
- Rate Limits — API usage limits