Keep the key on your server
Never put it in browser code, URLs, logs, analytics, or a storefront CORS request.
A narrow, read-only interface for reconciling existing Bulk PSN orders. It cannot create orders, start payments, reveal product codes, or register webhooks.
API access needs a separate review of the business relationship. A request alone does not grant access.
| Buyer profile | Review needed | Possible API result |
|---|---|---|
| Approved verified business | Operational fit and access decision | Credential limited to orders:read |
| Approved large buyer | Volume, support, and integration review | Credential within the agreed account scope |
| Approved contracted partner | Contract and technical acceptance | Credential with an explicit expiry |
| Registered account only | Continue through the dashboard | No automatic partner credential |
GET /api/partner/v1/orders/ lists orders for the approved account. Call it from your server. Page is 1–1000 and limit is 1–25; unknown query fields are rejected.
| Contract field | Required value | Boundary |
|---|---|---|
| Method | GET | The list is read-only and versioned under /api/partner/v1/ |
| URL | https://bulkpsn.com/api/partner/v1/orders/?page=1&limit=10 | page is 1-1000; limit is 1-25; unknown query fields fail closed |
| Authorization | Bearer $BULKPSN_API_KEY | The same approved orders:read credential is required |
| Response | orders + pagination | Only order metadata is returned; no account PII, product codes or payment data |
bashcurl --fail-with-body \
--request GET \
--header "Accept: application/json" \
--header "Authorization: Bearer $BULKPSN_API_KEY" \
"https://bulkpsn.com/api/partner/v1/orders/?page=1&limit=10"json{
"status": 200,
"code": "PARTNER_ORDERS_READY",
"orders": [],
"pagination": { "page": 1, "pageSize": 10, "totalCount": 0, "totalPages": 0 }
}GET /api/partner/v1/orders/{orderId}/ reads one order by its public UUID. The order and orders:read credential must belong to the same approved account. Responses are JSON with private no-store caching.
| Contract field | Required value | Boundary |
|---|---|---|
| Method | GET | Other operations are outside this v1 partner endpoint |
| URL | https://bulkpsn.com/api/partner/v1/orders/{orderId}/ | orderId is the UUID shown for the account's order |
| Authorization | Bearer $BULKPSN_API_KEY | Keep the key in a server-side secret store |
| Accept | application/json | Responses use JSON and private no-store caching |
| Scope | orders:read | The credential and order must belong to the same approved account |
bashcurl --fail-with-body \
--request GET \
--header "Accept: application/json" \
--header "Authorization: Bearer $BULKPSN_API_KEY" \
"https://bulkpsn.com/api/partner/v1/orders/$BULKPSN_ORDER_ID/"javascriptconst apiKey = process.env.BULKPSN_API_KEY;
const orderId = process.env.BULKPSN_ORDER_ID;
if (!apiKey || !orderId) throw new Error("API key and order ID are required");
const response = await fetch(
"https://bulkpsn.com/api/partner/v1/orders/" + encodeURIComponent(orderId) + "/",
{ method: "GET", headers: { Accept: "application/json", Authorization: "Bearer " + apiKey } }
);
const body = await response.json();
if (!response.ok) throw new Error("Bulk PSN API returned " + response.status);
console.log(body.order.state);json{
"status": 200,
"code": "PARTNER_ORDER_READY",
"order": {
"orderId": "8ceec955-7f27-45c0-aee1-8fa2f5333563",
"orderNumber": "BPSN-0123456789ABCDEF",
"state": "awaiting_payment",
"totalQuantity": 50,
"itemCount": 2,
"total": { "amount": "500.00", "currency": "USD" },
"createdAt": "2026-08-14T10:30:00.000Z"
}
}| HTTP | Code | Next action |
|---|---|---|
| 200 | PARTNER_ORDER_READY | Reconcile against the returned order state; a later read may show a change. |
| 401 | PARTNER_AUTHENTICATION_REQUIRED | Stop and replace, reactivate, or re-scope the credential through support. |
| 404 | PARTNER_ORDER_NOT_FOUND | Confirm the order ID belongs to the credential’s account. |
| 429 | RATE_LIMITED | Wait for Retry-After. |
| 503 | PARTNER_API_SERVICE_UNAVAILABLE | Treat state as unknown and wait for Retry-After. |
Never put it in browser code, URLs, logs, analytics, or a storefront CORS request.
Store request IDs for support correlation. A failed read is not a state change and is never a product-code delivery channel.