Connect your platform to PCC for seamless labor law poster fulfillment
As a dropship partner, you send orders and we ship directly to your customers under your contracted rates. Here's your simplified flow:
Here's exactly what your checkout request should look like:
POST /v1/checkout HTTP/1.1
Host: api.postercompliance.com
Authorization: Bearer YOUR_API_TOKEN
Content-Type: application/json
{
"account": {
"name": "John Smith",
"email": "john.smith@example.com",
"phone": "555-123-4567",
"shippingAddress": {
"line1": "123 Main Street",
"line2": "Suite 100",
"city": "Austin",
"stateOrProvince": "TX",
"postalCode": "78701",
"country": "US"
}
},
"order": {
"externalOrderNumber": "YOUR-ORDER-12345",
"orderType": "New",
"lineItems": [
{
"sku": "1-P-SP-TX-XX-A-E-L-0325",
"quantity": 1,
"pricePerUnit": 0
}
],
"shippingAmount": 0,
"taxAmount": 0,
"payment": {
"transactionId": "YOUR-ORDER-12345",
"paymentDate": "2026-02-15T10:00:00Z",
"amount": 0
}
}
}
Note: All pricing fields are $0 because PCC applies your contracted rates automatically.
Use "orderType": "Renewal" with originalOrderNumber for subscription renewals.
Add "testMode": true to test without creating real orders.
PCC will provide you with an API token. Include it in all requests:
Authorization: Bearer YOUR_API_TOKEN
Your token determines:
Retrieve our product catalog. Cache this data and refresh daily or weekly.
Request:
GET /v1/products HTTP/1.1
Host: api.postercompliance.com
Authorization: Bearer YOUR_API_TOKEN
Response:
{
"success": true,
"message": "Successfully retrieved 150 available products (price source: Default)",
"data": {
"products": [
{
"name": "California State & Federal Labor Law Poster - 1 Year Plan - AIO - English",
"productNumber": "1-P-SP-CA-XX-A-E-L-0325",
"price": 149.99,
"longDescription": "Comprehensive California state and federal labor law poster with all required postings, updated automatically for 1 year.",
"photoUrl": "https://api.postercompliance.com/v1/products/1-P-SP-CA-XX-A-E-L-0325/photo",
"details": {
"posterType": "SP",
"posterTypeDescription": "State Poster",
"state": "CA",
"stateName": "California",
"cityCounty": "XX",
"cityCountyDescription": "California Only",
"language": "English",
"languageDescription": "English",
"isStateFederal": true,
"isCityCounty": false,
"planTerm": 1,
"productType": "Plan",
"productTypeDescription": "1 Yr Plan",
"posterFormat": "AllInOne",
"posterFormatDescription": "All In One"
}
}
],
"totalCount": 150,
"priceLevelApplied": null,
"pricesOverridden": 0
}
}
| Field | Description |
|---|---|
productNumber |
Use this when placing orders. Unique product SKU identifier. |
price |
Retail price. Dropship partners: your contracted rate may differ. |
details.productType |
"Plan" (annual subscription with updates) or "Set" (one-time purchase) |
details.posterFormat |
"AllInOne" (single poster) or "SeparatePosters" (multiple posters) |
details.state |
2-letter state code (e.g., "CA", "TX", "NY") |
photoUrl |
Product image URL (can be null) |
longDescription |
Extended product description from Dynamics (can be null) |
?productType=Plan for subscriptions only, or ?productType=Set for one-time purchases.
productNumber value as the sku field when placing checkout orders.
For standard integrations where you collect payment, get the tax estimate first:
POST /v1/orders/estimate HTTP/1.1
Host: api.postercompliance.com
Authorization: Bearer YOUR_API_TOKEN
Content-Type: application/json
{
"shippingDestinations": [
{
"destinationId": "1",
"shippingAddress": {
"street": "123 Main Street",
"city": "Austin",
"state": "TX",
"zipCode": "78701"
},
"items": [
{
"productNumber": "1-P-SP-TX-XX-A-E-L-0325",
"quantity": 1,
"unitPrice": 149.99
}
],
"shippingAmount": 14.99
}
]
}
Response:
{
"success": true,
"message": "Successfully calculated estimate for 1 destinations",
"data": {
"orderId": null,
"destinationResults": [
{
"destinationId": "1",
"shippingAddress": {
"street": "123 Main Street",
"city": "Austin",
"state": "TX",
"zipCode": "78701",
"country": "US"
},
"subtotal": 149.99,
"shippingAmount": 14.99,
"taxAmount": 13.61,
"total": 178.59,
"lineItemTaxes": [
{
"lineId": null,
"productNumber": "1-P-SP-TX-XX-A-E-L-0325",
"quantity": 1,
"unitPrice": 149.99,
"extendedPrice": 149.99,
"taxAmount": 12.37,
"totalWithTax": 162.36
}
],
"taxCloudCartId": "abc123-def456",
"isExempt": false,
"taxCalculationSuccess": true,
"taxCalculationError": null
}
],
"totalTax": 13.61,
"totalSubtotal": 149.99,
"totalShipping": 14.99,
"grandTotal": 178.59
}
}
taxCalculationSuccess. If false, the tax couldn't be calculated - don't proceed to checkout.
Submit the order for fulfillment. Choose the tab that matches your scenario.
{
"account": {
"name": "Customer Name",
"email": "customer@email.com",
"phone": "555-123-4567",
"shippingAddress": {
"line1": "123 Main Street",
"city": "Austin",
"stateOrProvince": "TX",
"postalCode": "78701",
"country": "US"
}
},
"order": {
"externalOrderNumber": "YOUR-ORDER-ID",
"orderType": "New",
"lineItems": [
{
"sku": "1-P-SP-TX-XX-A-E-L-0325",
"quantity": 1,
"pricePerUnit": 0
}
],
"shippingAmount": 0,
"taxAmount": 0,
"payment": {
"transactionId": "YOUR-ORDER-ID",
"paymentDate": "2026-02-15T10:00:00Z",
"amount": 0
}
}
}
Dropship: All pricing fields are $0 - PCC applies your contracted rates.
Standard: Include actual prices. Total must match: lineItems + shipping + tax = payment.amount
{
"order": {
"externalOrderNumber": "YOUR-RENEWAL-ORDER-456",
"orderType": "Renewal",
"originalOrderNumber": "SO-2025-00001234",
"lineItems": [
{
"sku": "1-P-SP-TX-XX-A-E-L-0326",
"quantity": 1,
"pricePerUnit": 0
}
],
"shippingAmount": 0,
"taxAmount": 0,
"payment": {
"transactionId": "YOUR-RENEWAL-ORDER-456",
"paymentDate": "2026-02-15T10:00:00Z",
"amount": 0
}
}
}
Account is auto-resolved: For renewals, the shipping account is automatically looked up from the original order - you don't need to provide account details.
Update info on renewal: If you include account with new info (name, email, address), the account will be updated in our system and the new info used for this order.
Save the orderNumber from each order result to use as originalOrderNumber for future renewals.
{
"account": {
"name": "Test Customer",
"email": "test@example.com",
"shippingAddress": {
"line1": "123 Test Street",
"city": "Austin",
"stateOrProvince": "TX",
"postalCode": "78701",
"country": "US"
}
},
"order": {
"externalOrderNumber": "TEST-ORDER-001",
"orderType": "New",
"testMode": true,
"lineItems": [
{
"sku": "1-P-SP-TX-XX-A-E-L-0325",
"quantity": 1,
"pricePerUnit": 0
}
],
"shippingAmount": 0,
"taxAmount": 0,
"payment": {
"transactionId": "TEST-ORDER-001",
"paymentDate": "2026-02-15T10:00:00Z",
"amount": 0
}
}
}
Test mode validates without creating records - products, SKUs, tax calculation, and renewal links are all verified, but no accounts, orders, or invoices are created in Dynamics.
Perfect for development and integration testing. Response includes "testMode": true and simulated IDs (e.g., TEST-...).
Response:
{
"success": true,
"message": "Checkout queued successfully",
"data": {
"jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "Pending",
"externalOrderNumber": "YOUR-ORDER-ID",
"testMode": false,
"message": "Checkout order queued for processing",
"statusUrl": "/v1/jobs/a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
}
jobId to check status.
| Field | Required | Description |
|---|---|---|
accountNumber |
No | PCC account number if known (skips account lookup). For renewals, auto-resolved from original order. |
account.name |
New orders | Customer or company name. For renewals: optional, but if provided will update the account. |
account.email |
New orders | Customer email address. For renewals: optional, but if provided will update the account. |
account.shippingAddress |
New orders | Where to ship. For renewals: optional, but if provided will update the account. |
order.externalOrderNumber |
Yes | Your order ID for reference |
order.orderType |
No | "New" (default) or "Renewal" |
order.originalOrderNumber |
If renewal | PCC order number from original order (e.g., "SO-2025-00001234") |
order.testMode |
No | Set to true for development testing (default: false) |
order.lineItems |
Yes | Products to order (sku, quantity, pricePerUnit) |
order.payment |
Yes | Payment reference (transactionId, paymentDate, amount) |
Poll the status endpoint to see when your order completes.
GET /v1/jobs/a1b2c3d4-e5f6-7890-abcd-ef1234567890 HTTP/1.1
Host: api.postercompliance.com
Authorization: Bearer YOUR_API_TOKEN
Response (Completed):
{
"success": true,
"message": "Job retrieved successfully",
"data": {
"jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"jobType": "CheckoutOrder",
"status": "Completed",
"totalItems": 1,
"processedItems": 1,
"succeededItems": 1,
"failedItems": 0,
"progressPercent": 100,
"createdAt": "2026-02-15T10:00:00Z",
"startedAt": "2026-02-15T10:00:01Z",
"completedAt": "2026-02-15T10:00:15Z",
"errorMessage": null,
"checkoutResults": {
"success": true,
"message": "Checkout completed successfully",
"accountCreated": true,
"account": {
"accountId": "abc12345-1234-5678-9abc-def012345678",
"accountNumber": "1234567",
"name": "Customer Name",
"isNew": true,
"resolution": "Created new account"
},
"order": {
"success": true,
"message": "Order created successfully",
"salesOrder": {
"salesOrderId": "def45678-5678-9abc-def0-123456789abc",
"orderNumber": "SO-2026-00001234",
"subtotal": 149.99,
"taxAmount": 13.61,
"totalAmount": 178.59,
"lineItemCount": 2,
"lineItems": [
{
"lineItemId": "line-item-guid-1",
"sku": "1-P-SP-TX-XX-A-E-L-0325",
"productName": "Texas Labor Law Poster - 1 Year Plan",
"quantity": 1,
"pricePerUnit": 149.99,
"extendedAmount": 149.99
},
{
"lineItemId": "line-item-guid-2",
"sku": "N-S-SH-SD-XX-X-X-X-0000",
"productName": "Shipping Standard",
"quantity": 1,
"pricePerUnit": 14.99,
"extendedAmount": 14.99
}
]
},
"invoice": {
"invoiceId": "inv-guid-12345",
"invoiceNumber": "INV-2026-00001234",
"totalAmount": 178.59,
"taxAmount": 13.61,
"status": "Posted"
},
"payment": {
"paymentId": "pay-guid-12345",
"amount": 178.59,
"transactionId": "YOUR-ORDER-ID",
"recorded": true
},
"processingSteps": [],
"errors": []
},
"processingSteps": [],
"errors": []
}
}
}
checkoutResults.account.accountNumber - Reuse for future orders from same customercheckoutResults.order.salesOrder.orderNumber - Use to get tracking information| Status | Meaning | Action |
|---|---|---|
Pending |
Queued for processing | Wait 3-5 seconds, check again |
Processing |
Currently being processed | Wait 3-5 seconds, check again |
Completed |
Order created successfully | Save the orderNumber |
RetryPending |
Temporary failure, will retry automatically | Wait for scheduled retry (see errorMessage) |
Failed |
Error occurred (validation, bad data) | Check errorMessage, fix and resubmit |
PermanentlyFailed |
Failed after 5 retry attempts | Contact support or resubmit manually |
errorMessage field
shows the retry schedule.
Most orders complete within 30-60 seconds.
Once an order ships, retrieve the tracking number to share with your customer.
GET /v1/orders/SO-2026-00001234/tracking HTTP/1.1
Host: api.postercompliance.com
Authorization: Bearer YOUR_API_TOKEN
Response (Shipped):
{
"success": true,
"message": "Tracking information retrieved for order SO-2026-00001234",
"data": {
"orderNumber": "SO-2026-00001234",
"trackingNumber": "1Z999AA10123456784",
"found": true,
"isRenewal": false,
"errorMessage": null
}
}
Response (Not Yet Shipped):
{
"error": "NotFound",
"message": "Order 'SO-2026-00001234' not found or not in fulfilled status",
"traceId": "0HN4ABC123"
}
Response (Renewal Order):
{
"success": true,
"message": "Renewal order SO-2026-00001234 - no shipping required",
"data": {
"orderNumber": "SO-2026-00001234",
"trackingNumber": null,
"found": true,
"isRenewal": true,
"errorMessage": "Renewal orders do not require shipping and will not have tracking numbers"
}
}
Renewal orders do not require shipping and will not have tracking numbers.
When you query tracking for a renewal order, it will return isRenewal: true
with a message explaining that no shipping is required. You do not need to poll for tracking on renewal orders.
Check tracking for multiple orders at once:
Request:
POST /v1/orders/tracking HTTP/1.1
Host: api.postercompliance.com
Authorization: Bearer YOUR_API_TOKEN
Content-Type: application/json
{
"orderNumbers": [
"SO-2026-00001234",
"SO-2026-00001235",
"SO-2026-00001236"
]
}
Response:
{
"success": true,
"message": "Tracking information retrieved",
"data": {
"totalRequested": 3,
"totalFound": 2,
"results": [
{
"orderNumber": "SO-2026-00001234",
"trackingNumber": "1Z999AA10123456784",
"found": true,
"isRenewal": false,
"errorMessage": null
},
{
"orderNumber": "SO-2026-00001235",
"trackingNumber": null,
"found": true,
"isRenewal": true,
"errorMessage": "Renewal orders do not require shipping and will not have tracking numbers"
},
{
"orderNumber": "SO-2026-00001236",
"trackingNumber": null,
"found": false,
"isRenewal": false,
"errorMessage": "Order not found or not fulfilled"
}
]
}
}
When something goes wrong, you'll get a clear error response:
{
"error": "ValidationError",
"message": "Shipping address is required",
"details": null,
"traceId": "0HN4ABC123",
"timestamp": "2026-02-15T10:00:00Z",
"validationErrors": {
"account.shippingAddress": [
"Shipping address is required"
]
}
}
| Code | Meaning | What to Do |
|---|---|---|
400 |
Bad request / validation error | Check the error message and fix your request |
401 |
Not authenticated | Check your API token is correct |
403 |
Not authorized | Your token doesn't have access to this endpoint |
404 |
Not found | Check the order number or SKU exists |
429 |
Too many requests | Slow down and retry in a few seconds |
500 |
Server error | Retry later. Contact support if it persists. |
traceId from the error response when contacting support.