Carrier & Service Lookup
Discovering an Account’s Shipping Options — Non-Visual Shipping API Quick Start Guide
Overview
Before you can rate or ship, you need to know what a ShipRush account can actually do: which carriers it has, and which services each of those carriers offers. Two Non-Visual Shipping API calls answer exactly that, and they are designed to be used together:
POST /shipmentservice.svc/shipment/lookup/carriers — returns the carriers configured on the account.
POST /shipmentservice.svc/shipment/lookup/services — returns the services for one carrier you name.
Carrier Lookup takes no input and tells you which carriers are available. Service Lookup takes one of those carrier codes and tells you which services that carrier offers. Run the first, then loop the second over its results — and you have the account’s complete, live shipping menu.
The Discovery Workflow
Both lookups are the front half of a four-step path from “empty form” to “printed label”:
|
STEP 1 lookup/carriers Which carriers? |
→ |
STEP 2 lookup/services Which services? |
→ |
STEP 3 lookup/packaging Which packaging? |
→ |
STEP 4 rate / ship Price & label |
This guide covers Steps 1 and 2. Steps 3 and 4 (lookup/packaging and rate / ship) consume their output and are covered in their own guides.
Why chain them? Carrier and service codes vary by account and change over time (carriers get added; USPS retired products in 2023). Discovering them at runtime — rather than hard-coding — means your integration always offers exactly what the account can use, with no code change when its configuration changes.
Prerequisites & Authentication
Both calls share the same setup:
An active Descartes ShipRush Web account with at least one carrier configured.
A Shipping Token (X-SHIPRUSH-SHIPPING-TOKEN) — obtained from ShipRush Web under Settings → User Settings → Developer Tokens (enable 2FA, apply to the Shipping Developer Program, then Show Token). It scopes both lookups to that account.
A Developer Token (X-SHIPRUSH-DEVELOPER-TOKEN) issued to your developer account.
An HTTP client able to POST XML.
Heads up: The shipping token is shown only once and can ship against real accounts — store it like a password. Tokens are system-specific: sandbox tokens do not work in production, and vice versa.
Base URLs:
Production: https://api.my.shiprush.com
Sandbox: https://sandbox.api.my.shiprush.com
Both endpoints use the same HTTP headers:
Header |
Required |
Value |
X-SHIPRUSH-SHIPPING-TOKEN |
Yes |
Your account's shipping token. Scopes both lookups to that account. |
X-SHIPRUSH-DEVELOPER-TOKEN |
Yes |
Your developer/application token, issued to your developer account. |
Content-Type |
Yes |
application/xml (or text/xml) |
Accept-Encoding |
Yes |
gzip, deflate — your client must accept compressed responses. |
User-Agent |
Yes |
Identifies your app clearly, e.g. Acme-OrderSystem. Spaces → hyphen/underscore. |
X-SHIPRUSH-VERSION |
No |
Desired XML response version, e.g. 84114. Omit to use the server default. |
User-Agent-Version |
No |
Full build of your app, e.g. 1.0.0.1234. |
Step 1 — Carrier Lookup
POST an empty GetCarrierTypesRequest to /shipmentservice.svc/shipment/lookup/carriers. No carrier is supplied — the account (via its token) determines the result.
Request:
<?xml version="1.0" encoding="utf-8"?>
<GetCarrierTypesRequest />
Response (an account with FedEx, USPS, and ShipRush USPS):
<GetCarrierTypesResponse>
<IsSuccess>true</IsSuccess>
<Messages />
<CarrierTypes>
<TCarrierType>1</TCarrierType> <!-- FedEx -->
<TCarrierType>3</TCarrierType> <!-- USPS -->
<TCarrierType>17</TCarrierType> <!-- ShipRush USPS -->
</CarrierTypes>
</GetCarrierTypesResponse>
Carrier codes (the account returns only the codes it has configured; full master enum for reference):
Code |
Carrier |
Code |
Carrier |
0 |
UPS |
24 |
EasyPost APC |
1 |
FedEx |
25 |
EasyPost RRD |
2 |
DHL |
26 |
EasyPost Asendia |
3 |
USPS |
27 |
EasyPost Globegistics |
4 |
Endicia |
28 |
EasyPost DHL Intl |
5 |
Stamps |
29 |
DHL eC |
6 |
USS Prefership |
30 |
Amazon FBA |
7 |
Unknown |
31 |
Banyan |
8 |
FedEx FIMS |
32 |
FirstMile |
9 |
Direct Link |
33 |
PlainLabel |
10 |
Amazon |
34 |
Canada Post |
11 |
MailView |
35 |
DHL Paket |
12 |
Pitney Bowes |
36 |
LSO |
13 |
WWEX |
37 |
L5 |
14 |
WWEX LTL |
38 |
Canpar |
15 |
Deliv |
39 |
Newgistics |
16 |
OnTrac |
40 |
ChitChats |
17 |
ShipRush USPS |
41 |
Hogwarts Post |
18 |
EasyPost USPS |
42 |
Amazon Shipping |
19 |
MailView v2 |
43 |
TNT Express |
20 |
FIMS2 |
44 |
NZ Couriers |
21 |
Direct Link v2 |
45 |
GLS |
22 |
Project44 |
46 |
Paquet Express |
23 |
EasyPost DHL |
999 |
Parcel Partners |
Step 2 — Service Lookup
Take a carrier code from Step 1 and POST it in a GetServiceTypesRequest to /shipmentservice.svc/shipment/lookup/services. <CarrierType> is required.
Request (using carrier 17 from Step 1):
<?xml version="1.0" encoding="utf-8"?>
<GetServiceTypesRequest>
<CarrierType>17</CarrierType>
</GetServiceTypesRequest>
Response (domestic USPS services):
<GetServiceTypesResponse>
<IsSuccess>true</IsSuccess>
<Messages />
<ServiceTypes>
<TUPSService>U01</TUPSService> <!-- USPS First Class -->
<TUPSService>U02</TUPSService> <!-- USPS Priority -->
<TUPSService>U05</TUPSService> <!-- USPS Express -->
<TUPSService>USPSGNDADV</TUPSService> <!-- USPS Ground Advantage -->
</ServiceTypes>
</GetServiceTypesResponse>
Element naming: Service codes always come back inside <TUPSService> elements — a legacy name used for every carrier, not just USPS. The codes themselves are carrier-specific: FedEx returns FedEx codes, UPS returns UPS codes, and so on.
Common USPS service codes (carrier 17). For other carriers, treat the lookup response as authoritative.
Service Code |
Service |
Scope |
U01 |
USPS First Class |
Domestic |
U02 |
USPS Priority |
Domestic |
U03 |
USPS Media Mail |
Domestic |
U05 |
USPS Express |
Domestic |
U07 |
USPS Library Mail |
Domestic |
USPSGNDADV |
USPS Ground Advantage |
Domestic |
UI01 |
USPS Intl First Class |
International |
UI02 |
USPS Intl Priority |
International |
UI05 |
USPS Intl Express |
International |
USPS Ground Advantage: Uses the wire code USPSGNDADV, not a Uxx code. It replaced U04 and U08 when USPS retired those in 2023; U06 is obsolete. International on carrier 17 returns UI01, UI02, UI05.
Putting It Together
The two calls chain naturally: discover carriers, then discover each carrier’s services.
Call lookup/carriers once → get the account’s carrier codes.
For each carrier code, call lookup/services → get that carrier’s service codes.
Cache the result per account and refresh periodically (e.g. daily), since configuration can change.
This C# example does exactly that — one carriers call, then a services call per returned carrier, using a shared POST helper:
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
class ShipRushLookups
{
const string BaseUrl = "https://sandbox.api.my.shiprush.com"; // prod: https://api.my.shiprush.com
const string ShippingToken = "YOUR-SHIPPING-TOKEN-GUID";
const string DeveloperToken = "YOUR-DEVELOPER-TOKEN";
static async Task Main()
{
// STEP 1: which carriers does this account have?
var carriers = await Post(
"lookup/carriers",
"<GetCarrierTypesRequest />",
"TCarrierType");
// STEP 2: for each carrier, which services can it use?
foreach (var carrier in carriers)
{
var body = $"<GetServiceTypesRequest><CarrierType>{carrier}" +
"</CarrierType></GetServiceTypesRequest>";
var services = await Post("lookup/services", body, "TUPSService");
Console.WriteLine($"Carrier {carrier}: {string.Join(\", \", services)}");
}
}
// POSTs an XML body and returns the inner text of every <elementName> node.
static async Task<List<string>> Post(string path, string innerXml, string elementName)
{
var xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + innerXml;
using var client = new HttpClient();
var req = new HttpRequestMessage(
HttpMethod.Post, $"{BaseUrl}/shipmentservice.svc/shipment/{path}");
req.Headers.Add("X-SHIPRUSH-SHIPPING-TOKEN", ShippingToken);
req.Headers.Add("X-SHIPRUSH-DEVELOPER-TOKEN", DeveloperToken);
req.Headers.Add("Accept-Encoding", "gzip, deflate");
req.Headers.UserAgent.ParseAdd("Acme-OrderSystem/1.0");
req.Content = new StringContent(xml, Encoding.UTF8, "application/xml");
var resp = await client.SendAsync(req);
var text = await resp.Content.ReadAsStringAsync();
var doc = XDocument.Parse(text);
var list = new List<string>();
foreach (var e in doc.Descendants(elementName)) list.Add(e.Value);
return list;
}
}
Error Handling
Both endpoints share the Non-Visual Shipping API’s two-level result model:
HTTP 200 — structurally accepted. Read <IsSuccess> / <Messages> in the body for the real outcome.
HTTP 401 — authentication failed (bad or missing token).
HTTP 500 — a structural or authentication failure; the body is a JSON error object, not XML.
An empty <CarrierTypes> or <ServiceTypes> list is a valid response — treat it as “nothing configured” rather than an error.
Quick Reference
The Two Calls
Carriers: POST …/lookup/carriers body <GetCarrierTypesRequest /> → <CarrierTypes>/<TCarrierType>
Services: POST …/lookup/services body <GetServiceTypesRequest><CarrierType>N</CarrierType>… → <ServiceTypes>/<TUPSService>
Auth (both): X-SHIPRUSH-SHIPPING-TOKEN + X-SHIPRUSH-DEVELOPER-TOKEN headers.
Next Steps
Feed a carrier + service into POST …/shipment/lookup/packaging to list packaging options.
Then call shipment/rate to price, or shipment/ship to buy a label, with the carrier, service, and packaging you selected.
See the individual Carrier Lookup and Service Lookup Quick Start Guides for endpoint-specific detail.