Using the API to Execute a Shipping Request
The information in Requesting Shipment: Introduction applies to this method.
Listing Shipments
There is a 100-record limit on all API calls. To illustrate, using /shipments_exact
to retrieve a list of all shipments would be unsuccessful unless there were only one hundred or fewer shipments, as only the first 100 records are returned.
Obtaining Further Records
In cases where there are more than 100 shipments, iterate through the shipments based on the number of shipments provided by the total_count
parameter.
Use the optional parameters to obtain more records. For example:
// get the first 100
/shipments_exact?limit=100&offset=0
// get the second 100
/shipments_exact?limit=100&offset=100
// get the third 100
/shipments_exact?limit=100&offset=200
Channel Partners
To order keys via API from inventory purchased through channel partners, the new /shipments_exact
APIs must be used; see Deprecated APIs below. The older, deprecated /shipments
API only supports ordering keys from inventory purchased directly from Yubico.
The following APIs related to bulk shipments have been updated to handle channel partners:
POST /shipments/bulk
GET /shipments/bulk
POST /shipments/bulkvalidate
POST /shipments/bulkdelete
- For the sake of completeness, this is included in the list, but it has not changed.
The GET /shipments/csv
API will also be updated to support channel partners.
Single Orders
To order keys via API from inventory purchased through channel partners, the new /shipments_exact
APIs must be used. The APIs modified to handle channel partners are:
GET /shipments_exact
POST /shipments_exact
GET /shipments_exact/{shipmentId}
PUT /shipments_exact
The corresponding deprecated /shipments
have not been modified and can only handle inventory purchased directly from Yubico.
Bulk Orders
Bulk orders using the API are still handled through the GET /shipments/bulk
, POST /shipments/bulk
, POST /shipments/bulkvalidate
, and POST /shipments/bulkdelete
APIs. The API parameters and request body themselves did not change to work with channel partners. Instead, it is the content of the .csv file used in the upload that has been changed to include the new channel_partner_ID field. The channel partner ID is a non-zero integer shown as a field on the purchase order table and on the purchase order details page.
Note
To ensure you are using the latest .csv file format, make a practice of downloading the template file anew each time before uploading a new set of orders.
Verifying Inventory
Verify that all the products you intend to ship are currently available in inventory.
/shippablekeys
returns all products associated with your organization’s account, including any products that have a current available inventory of 0.- When
inventory_type
is1
, products that have zero inventory are not listed. The quantities of the products available are shown next to the names of the products. Therefore, even if a product is shown on a PO, if its inventory is exhausted by the time you want to request it be shipped, this API will not return it.
Shipment Request Fields
Shipment Request Fields
In the table below, all fields not marked as mandatory are optional. The Limit column displays the maximum number of alphanumeric characters permitted per field/table cell.
Console: Field Label
CSV: Column Heading
|
Description | Limit |
---|---|---|
Country code
country_code_2 |
Mandatory. Country code from available_countries.csv | 2 |
Company recipient |
Mandatory if name of recipient is not provided | 20 |
First name
recipient_firstname |
Name of recipient. Mandatory if company name not given | 15 |
Last name
recipient_lastname |
Recipient’s family name. Mandatory, absent company name | 20 |
Address 1
street_line1 |
Mandatory. First line of address | 60 |
Address 2
street_line2 |
Mandatory if address undeliverable without (e.g. suite #) | 60 |
Address 3
street_line3 |
Not supported for expedited/rush orders | 60 |
City | Mandatory. City, town, or township | 60 |
Region/State
region |
For the US and Canada, USPS codes are mandatory. See
USPS Codes for US and Canada. (Console users: Select code
from dropdown). For other countries, region or state is
mandatory if the address is not deliverable without it.
To check address deliverability, see footnote to table.
|
50 |
Postcode
postal_code |
Zip code or postal code | 50 |
RecipientEmail
recipient_email |
Recipient’s email address | 40 |
Contact Phone
RecipientTelephone
recipient_telephone |
Telephone number of shipment recipient
The limit is 40 of the alphanumeric characters
“0-9+-( )” unless the country code is IN, in which
case the limit is 255. Any format is acceptable,
with or without spaces
|
40 |
DeliveryType
delivery_type |
Type of shipping, “Normal” (1) or “Expedited” (2).
Integers (mandatory for API) OR words
|
– |
InventoryType | Mandatory. Console users select from dropdown. | – |
ChannelPartnerId
channel_partner_ID |
Mandatory. If inventory was purchased directly from
Yubico, enter “1”; if not, enter the ChannelPartnerId
|
3 |
Security Key NFC by Yubico | Number of keys to be shipped | 3 |
Yubikey 5 NFC | Number of keys to be shipped | 3 |
YubiKey 5 Nano | Number of keys to be shipped | 3 |
YubiKey 5C | Number of keys to be shipped | 3 |
YubiKey 5C Nano | Number of keys to be shipped | 3 |
YubiKey 5C NFC | Number of keys to be shipped | 3 |
YubiKey 5Ci | Number of keys to be shipped | 3 |
YubiKey 5 NFC FIPS | Number of keys to be shipped | 3 |
YubiKey 5 Nano FIPS | Number of keys to be shipped | 3 |
YubiKey 5C FIPS | Number of keys to be shipped | 3 |
YubiKey 5C Nano FIPS | Number of keys to be shipped | 3 |
YubiKey 5C NFC FIPS | Number of keys to be shipped | 3 |
YubiKey 5Ci FIPS | Number of keys to be shipped | 3 |
Footnote: To find out if an address is deliverable, make a shipment request and see what status code or message it gets. Deliverability is determined by our shipping partners, and it is their codes and messages we display when it comes to questions of deliverability. For a fuller explanation, see Troubleshooting.
Name
Recipient Names
On the Console, in the API and in the CSV file: recipient_firstname
and recipient_lastname
map to the first line on the shipping label.
For commercial or business addresses, the API’s recipient
field and the Company field on the Console and in the CSV file all require the name of the recipient’s company. This is not necessarily the same as the name of your organization. For residential addresses, leave the Company / recipient
field empty.
The Company / recipient
fields map to the second line on the shipping label.
Long recipient names can be problematic for all methods of requesting shipment, because the shipment request will fail if the contents of the name and/or Company / recipient
fields exceed the maximum number of characters permitted in these fields (shown in the table below).
Workaround: When a recipient’s full name or company name exceeds the fields’ maximum lengths, split the names across the three fields, for example:
Location | Field (limit=15) | Limit | Field (limit=20) | Limit | Field (limit=20) | Limit |
---|---|---|---|---|---|---|
API | recipient_firstname |
15 | recipient_lastname |
20 | recipient |
20 |
CSV | recipient_firstname | 15 | recipient_lastname | 20 | recipient_company | 20 |
Console | First name | 15 | Last name | 20 | Company | 20 |
Example of an overly long name before adjustment to fit the fields | ||||||
Johannes-Maximilian | von Derschowitz-Dampfloch zu Querdenker | |||||
Example after adjustment | ||||||
Joh.-Maximilian | v.DerschowitzDampfloch | zu Querdenker |
Note
The recipient
field requires the name of the recipient’s company (if applicable) in the shipment address. Do not use the /shipments recipient
field to specify the name of the individual to whom products are to be shipped. Use the recipient_firstname
and recipient_last name
fields instead.
Although the system can deliver to Post Office (PO) Boxes within the United States, delivery to PO Boxes (or the equivalent) elsewhere in the world is unlikely to succeed.
Region
USPS Codes for US and Canada
For shipments going to the US and Canada, the region
field requires the standardized two-letter USPS code. These codes are listed below.
State (US) / Province or Territory (Canada) | Code |
---|---|
Alabama | AL |
Alaska | AK |
Alberta | AB |
Arizona | AZ |
Arkansas | AR |
British Columbia/Colombie-Britannique | BC |
California | CA |
Colorado | CO |
Connecticut | CT |
Delaware | DE |
District of Columbia | DC |
Florida | FL |
Georgia | GA |
Hawaii | HI |
Idaho | ID |
Illinois | IL |
Indiana | IN |
Iowa | IA |
Kansas | KS |
Kentucky | KY |
Louisiana | LA |
Maine | ME |
Manitoba | MB |
Maryland | MD |
Massachusetts | MA |
Michigan | MI |
Minnesota | MN |
Mississippi | MS |
Missouri | MO |
Montana | MT |
Nebraska | NE |
Nevada | NV |
New Brunswick/Nouveau-Brunswick | NB |
New Hampshire | NH |
New Jersey | NJ |
New Mexico | NM |
New York | NY |
Newfoundland/Terre-Neuve | NF |
North Carolina | NC |
North Dakota | ND |
Northwest Territories/Territoires du Nord-Ouest | NT |
Nova Scotia/Nouvelle-Écosse | NS |
Nunavut | NU |
Ohio | OH |
Oklahoma | OK |
Ontario | ON |
Oregon | OR |
Pennsylvania | PA |
Prince Edward Island/Île-du-Prince-Édouard | PE |
Puerto Rico | PR |
Quebec/Québec | QC |
Rhode Island | RI |
Saskatchewan | SK |
South Carolina | SC |
South Dakota | SD |
Tennessee | TN |
Texas | TX |
Utah | UT |
Vermont | VT |
Virginia | VA |
Washington | WA |
West Virginia | WV |
Wisconsin | WI |
Wyoming | WY |
Yukon | YK |
Inventory Product ID and Product ID
Both of these values need to be supplied, product_id
and inventory_product_id
. The product_id
is the unique identifier for the product, e.g., 4
is the YubiKey 5C Nano, while the inventory_product_id
can be thought of as the ID for a “bucket” containing credits that your organization bought to cover the purchase of keys, lanyards, etc. Typically organizations with subscriptions have multiple “buckets”, while organizations that have bought physical keys outright might have only a single “bucket.”
Use the inventory_product_id
to specify which inventory you are pulling from. The inventories correspond exactly to:
- The inventories shown on the YubiEnterprise Console Dashboard and
- The options in the Choose from stock dropdown on the Single shipment tab accessed by clicking Create Shipment Request on the Shipments screen.
The table below lists both product_id
and inventory_product_id
in the same column, and contains all inventories and products except custom products. To get the complete list of products and inventories available to your organization, make a call to GET /inventory
. If you have custom products, that will return a list that also contains your custom products.
Mapping further down in this section also deals with the relationship between these two entities.
Note
The inventory_product_id
can have the same value as the product_id
field in the individual inventory_records
.
inventory _product_id product_id | product_name |
---|---|
1 | YubiKey 5 NFC |
2 | YubiKey 5 Nano |
3 | YubiKey 5C |
4 | YubiKey 5C Nano |
5 | YubiKey 5Ci |
7 | Security Key NFC by Yubico |
8 | YubiKey FIPS |
9 | YubiKey Nano FIPS |
10 | YubiKey C FIPS |
11 | YubiKey C Nano FIPS |
12 | Primary Subscr - Base Tier: Initial |
13 | Primary Subscr - Base Tier: Buffer |
14 | Primary Subscr - Base Tier: Replacement |
15 | Primary Subscr - Adv. Tier: Initial |
16 | Primary Subscr - Adv. Tier: Buffer |
17 | Primary Subscr - Adv. Tier: Replacement |
18 | Primary Subscr - Prem. Tier: Initial |
19 | Primary Subscr - Prem. Tier: Buffer |
20 | Primary Subscr - Prem. Tier: Replacement |
21 | Primary Subscr - FIPS Tier: Initial |
22 | Primary Subscr - FIPS Tier: Buffer |
23 | Primary Subscr - FIPS Tier: Replacement |
24 | Non-subscription - Base Tier |
25 | Non-subscription - Advanced Tier |
26 | Non-subscription - Premium Tier |
27 | Non-subscription - FIPS Tier |
28 | YubiKey Lanyard |
29 | YubiKey 5C NFC |
38 | Backup Subscr - Base Tier: Initial |
39 | Backup Subscr - Base Tier: Buffer |
40 | Backup Subscr - Base Tier: Replacement |
41 | Backup Subscr - Adv. Tier: Initial |
42 | Backup Subscr - Adv. Tier: Buffer |
43 | Backup Subscr - Adv. Tier: Replacement |
44 | Backup Subscr - Prem. Tier: Initial |
45 | Backup Subscr - Prem. Tier: Buffer |
46 | Backup Subscr - Prem. Tier: Replacement |
47 | Backup Subscr - FIPS Tier: Initial |
48 | Backup Subscr - FIPS Tier: Buffer |
49 | Backup Subscr - FIPS Tier: Replacement |
54 | YubiKey 5 NFC FIPS |
55 | YubiKey 5C NFC FIPS |
56 | YubiKey 5Ci FIPS |
57 | YubiKey 5 Nano FIPS |
58 | YubiKey 5C FIPS |
59 | YubiKey 5C Nano FIPS |
Mapping
Use the product_id
to map to the inventory_product_id
of the shipments_exact
request as shown in the /inventory
example output below.
Custom-programmed YubiKeys
If your organization has custom-programmed YubiKeys, to make a shipment request, use the /inventory /products
APIs to get the inventory_product_id
and product_id
. Using standard product_id codes
in shipment requests will result in errors.
/inventory
Example Output
{
"count": 3,
"total_count": 3,
"organization_product_inventory": [
{
"organization_product_inventory_id": "Cym9ypJsmVEshX9qzSQc7S",
"is_subscription_product": true,
"is_virtual_product": true,
"organization_id": "UEayb8v4LTHdAshpnk1gMd",
"organization_product_quantity": 978,
"product_id": 15,
"inventory_type": 3,
"product_name": "Primary Subscr - Adv. Tier: Initial",
"product_tier": 2
,"product_mapping": [
1,
2,
3,
4,
6,
7]
},
{
"organization_product_inventory_id": "Ky8VzJWpftEk2hiMsJDjVW",
"is_subscription_product": true,
"is_virtual_product": true,
"organization_id": "UEayb8v4LTHdAshpnk1gMd",
"organization_product_quantity": 10,
"product_id": 44,
"inventory_type": 3,
"product_name": "Backup Subscr - Prem. Tier: Initial",
"product_tier": 3,
"product_mapping": [
1,
2,
3,
4,
5,
6,
7]
},
{
"organization_product_inventory_id": "UPjT3FU8oqCoHPCr9mNUzD",
"is_subscription_product": true,
"is_virtual_product": true,
"organization_id": "UEayb8v4LTHdAshpnk1gMd",
"organization_product_quantity": 964,
"product_id": 18,
"inventory_type": 3,
"product_name": "Primary Subscr - Prem. Tier: Initial",
"product_tier": 3,
"product_mapping": [
1,
2,
3,
4,
5,
6,
7]
}
]
}
Example 1: Without Subscription
For example, if you do not have a subscription and simply bought outright a number of YubiKey 5C Nanos (no virtual keys, no tiers), your request for a single shipment would look like this:
{
"delivery_type": 1,
"country_code_2": "US",
"recipient": "string",
"recipient_email": "string",
"recipient_firstname": "string",
"recipient_lastname": "string",
"recipient_telephone": "string",
"street_line1": "string",
"street_line2": "string",
"street_line3": "string",
"city": "string",
"region": "string",
"postal_code": "string",
"shipment_items": [
{
"product_id": 4,
"inventory_product_id": 4,
"shipment_product_quantity": 1
}
]
}
Example 2: With Subscription
With a subscription, your product_id
value and your inventory_product_id
value would not coincide, and your individual shipment request would look like this:
{
"delivery_type": 1,
"country_code_2": "US",
"recipient": "string",
"recipient_email": "string",
"recipient_firstname": "string",
"recipient_lastname": "string",
"recipient_telephone": "string",
"street_line1": "string",
"street_line2": "string",
"street_line3": "string",
"city": "string",
"region": "string",
"postal_code": "string",
"shipment_items": [
{
"product_id": 4,
"inventory_product_id": 15,
"shipment_product_quantity": 1
}
]
}
Telephone Number
It is mandatory that the recipient_telephone
field be populated. This is the number at which the recipient of the shipment can be reached, designated on the Console as Contact Phone.
The permissible content of this, [+()\-0-9\s]+
, should match regular expression.
For /v1/shipments_exact
the API validates the existence of recipient_telephone
in the request body. If the country code is IN, the limit is 255 of the alphanumeric characters specified above while all other country codes limit recipient_telephone
to 40.
For CSV upload via /v1/bulkvalidate
, the API validates the existence of recipient_telephone
on each row. If the country code is IN, the limit is 255 of the alphanumeric characters specified above, while all other country codes limit recipient_telephone
to 40.
Error Messages
In the API
The following response is sent if recipient_telephone
is not included in the request to create shipment at shipments_exact
as per POST /v1/shipments_exact
:
400 Bad Request {
code: 'validation_error',
message: 'We were unable to create the shipment',
errors: [
{
field: 'recipient_telephone',
message: 'recipient_telephone is a required field'
}
]
}
In the CSV
When uploading a CSV file with no recipient_telephone
provided in one or more rows:
YRIEIXLECHAT-01:shipments yrieix.lechat$ cat my-shipments.csv
Country code 2,Company,First name,Last name,Address 1,Address 2,Address 3,City,Region/State,Postcode,RecipientEmail,RecipientTelephone,DeliveryType,InventoryType,ChannelPartnerId,YubiKey 5 NFC,YubiKey 5 Nano,YubiKey 5C,YubiKey 5C Nano,YubiKey 5Ci,Security Key NFC by Yubico,YubiKey FIPS,YubiKey Nano FIPS,YubiKey C FIPS,YubiKey C Nano FIPS
US,My Company,Yrieix,LeChat,123 Home Ave,,,Brooklyn,NY,11111,y.lechat@yubico.com,,Normal,1,1,0,0,0,0,0,1,0,0,0,0
YRIEIXLECHAT-01:shipments yrieix.lechat$ curl -v -s -X POST -H "Authorization: Bearer ..." -F file=@./my-shipments.csv http://api.console.local/v1/shipments/bulkvalidate | json_pp
...
> POST /v1/shipments/bulkvalidate HTTP/1.1
> Host: api.console.local
...
< HTTP/1.1 200 OK
...
{
"csv_filename" : "my-shipments.csv",
"failed_rows" : [
{
"fatal_messages" : "recipient_telephone is a required field",
"row_number" : 2
}
],
"lines_in_file" : 2,
"lines_not_parsable" : 1,
"lines_read" : 1
}
ShipmentDeliveryTypeEnum
ShipmentDeliveryTypeEnum
specifies the method of shipping:
- 1 - Normal (standard) shipping (default)
- 2 - Expedited (rush) shipping.
inventory_type and InventoryTypeEnum
The inventory_type
requires one of the values given in the InventoryTypeEnum
table below.
InventoryTypeEnum
Integer | inventory_type (Stock) | Purchase Mode |
---|---|---|
1 | Standard Product | Outright purchase |
2 | Non-subscription | Purchase of virtual keys |
3 | Subscription - Initial Shipment | Subscription |
4 | Subscription - Buffer Stock Shipment | Subscription |
5 | Subscription - Replacement YubiKey Shipment | Subscription |
- If you have purchased keys on the perpetual mode and/or lanyards, use Inventory Type 1.
- If you are not a subscription customer, but have purchased one or more tiers of virtual keys instead of physical keys, use Inventory Type 2, YubiKey Tier SKU Shipment.
- Subscription customers: Use Inventory Types 3, 4, and 5.
Initial | The stock in this category reflects the
total number of users on the subscription. This
lot can be drawn upon for 12 months from the
start of your subscription term.
|
Buffer | This category is made available to you free of
charge when your subscription begins. You can
draw on it throughout the term of your
subscription.
|
Replacement | This category is intended for those who have
lost their YubiKeys or want to upgrade. The
stock in this category is reset each year of
the subscription to the Replacement limit.
|
- Use up all of your Inventory Type 3, Initial, within the first year of your subscription.
- Use Inventory Type 4 at any time: Buffer stock expires only at the end of your subscription term.
- Use Inventory Type 5, Replacement, for users who have lost their keys or want to upgrade. Any keys not used in a given year are forfeited at the end of that year.
Shipping Products to a Single Address
Use the /shipments_exact
APIs for any new development and to update clients in existence prior to YubiEnterprise Delivery 1.6.0.
Specifying the stock/inventory to be used for an individual shipment request provides a much larger range of options than those available for bulk shipments.
Single Shipment Example Input
The following Curl example sends an HTTP POST to the shipments_exact
resource URI to ship a YubiKey 5 NFC to a fictional employee, Jan Lindberg:
curl "https://api.console.yubico.com/v1/shipments_exact" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer eyJhb..." \
--data '{
{
"delivery_type": 1,
"country_code_2": "US",
"recipient": "Example Inc.",
"recipient_email": "jan.lindberg@example.com",
"recipient_firstname": "Jan",
"recipient_lastname": "Lindberg",
"recipient_telephone": "555-5555",
"street_line1": "7788 Foxrun Street",
"street_line2": "",
"street_line3": "",
"city": "Dedham",
"region": "MA",
"postal_code": "02026",
"shipment_items": [
{"product_id": 3,
"inventory_product_id": 15,
"shipment_product_quantity": 16}
]
}'
In the example above, you will notice the delivery_type
is set to 1
which means it is a normal shipment. A value of 2
would request an expedited shipment. The recipient_email
gives the address at which the recipient will receive an email with the tracking number of the shipment.
Single Shipment Example Output
{
"shipment_id": "U89bvfKKCtQfhnqaFBrAZW",
"shipment_items": [
{
"inventory_product_id": 15,
"shipment_product_id": "MZ9bmEYFpKKviHe8nSiq4W",
"shipment_id": "U89bvfKKCtQfhnqaFBrAZW",
"product_id": 3,
"product_name": "YubiKey 5C",
"product_sku": "5060408461488",
"product_tier": 2,
"shipment_product_quantity": 16
}
],
"organization_id": "UEayb8v4LTHdAshpnk1gMd",
"user_id": "WMktp3sgPSFt4zsgpLDF46",
"country_code_2": "US",
"is_delivered": false,
"is_sent_to_fulfillment": false,
"is_shipped": false,
"recipient": "Example Inc.",
"recipient_email": "jan.lindberg@example.com",
"recipient_firstname": "Jan",
"recipient_lastname": "Lindberg",
"recipient_telephone": "555-5555",
"street_line1": "7788 Foxrun Street",
"city": "Dedham",
"region": "MA",
"postal_code": "02026",
"delivery_type": 1,
"shipment_state_code": "ShipmentStateAwaitingValidation",
"shipment_state_id": 3,
"shipment_state_message": "Awaiting Validation",
"shipment_summary_description": "Total Keys: 16 yk5c:16",
"shipment_request_date": "2020-12-10T19:56:57Z",
"shipment_updated_date": "2020-12-10T19:56:57Z",
"total_keys_shipped": 16
}
Shipping Products to Multiple Addresses
The system chooses the stock (inventory) from which products are drawn.
Example
The following example of a Bash script calls Curl to upload a CSV file with multiple shipment requests. To scroll horizontally, click in the code box below.
#!/bin/bash
token="apitokengoeshere"
curl -F "file=@/path/to/file/bulk_shipment.csv" https://api.console.yubico.com/v1/shipments/bulkvalidate \
--header "x-authorization: Bearer ${token}"
For instructions on creating and populating the CSV file, see Bulk Upload: Shipping to Multiple Addresses.
Validating CSV Uploads
lines-in-file | Lines in the file, including header.
|
lines_read | Lines that were able to be read in as
CSV, excluding the header. lines_read
should thus be one less than lines_in_file
|
lines_parsable | Lines that passed basic validation.
lines_parsable + lines_not_parsable =
lines_read.
|
Example: If a file that is not in the CSV format is uploaded, even if it had 100 lines, 0 lines would be read, because the CSV reader function cannot read the lines in as CSV.
Example: If a file has too many columns - i.e., more columns than the header row has - 0 lines would be read.
Examples of Error Messages
- Error with GetCountryByTwoLetterCode for CountryCode2: TT
- InventoryType not set for Shipment, defaulting to 1
- DeliveryType not set for Shipment, defaulting to 1 - normal
- Wrong number of fields
Tracking Shipment Requests
Single Shipment Request Tracking Example
A successful response from the shipments_exact
resource will include a shipment_id
which can be used to get the tracking information for this shipment request.
{
"shipment_id": "U89bvfKKCtQfhnqaFBrAZW",
"shipment_items": [
{
"inventory_product_id": 15,
"shipment_product_id": "MZ9bmEYFpKKviHe8nSiq4W",
"shipment_id": "U89bvfKKCtQfhnqaFBrAZW",
"product_id": 3,
"product_name": "YubiKey 5C",
"product_sku": "5060408461488",
"product_tier": 2,
"shipment_product_quantity": 16
}
],
"organization_id": "UEayb8v4LTHdAshpnk1gMd",
"user_id": "WMktp3sgPSFt4zsgpLDF46",
"country_code_2": "US",
"is_delivered": false,
"is_sent_to_fulfillment": false,
"is_shipped": false,
"recipient": "Example Inc.",
"recipient_email": "jan.lindberg@example.com",
"recipient_firstname": "Jan",
"recipient_lastname": "Lindberg",
"recipient_telephone": "555-5555",
"street_line1": "7788 Foxrun Street",
"city": "Dedham",
"region": "MA",
"postal_code": "02026",
"delivery_type": 1,
"shipment_state_code": "ShipmentStateAwaitingValidation",
"shipment_state_id": 3,
"shipment_state_message": "Awaiting Validation",
"shipment_summary_description": "Total Keys: 16 yk5c:16",
"shipment_request_date": "2020-12-10T19:56:57Z",
"shipment_updated_date": "2020-12-10T19:56:57Z",
"total_keys_shipped": 16
}
Tracking a Shipment Using the shipment_id
curl "https://api.console.yubico.com/v1/shipments_exact/Bj4pfrBJ1SCvkTbTP88Ak2" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer eyJhb..." \
Deprecated APIs
Deprecated | Replacement |
---|---|
GET /shipments |
GET /shipments_exact |
POST /shipments |
POST /shipments_exact |
GET /shipments/{shipmentId} |
GET /shipments_exact/{shipmentId} |
PUT /shipments/{shipmentId} |
PUT /shipments_exact/{shipmentId} |
DELETE /shipments/{shipmentId} |
DELETE /shipments_exact/{shipmentId} |
/UpdateShipmentById |
shipments_exact/{shipment_id} |
Search
Some of the lines of code are very long, so it may be necessary to click in the line and scroll horizontally.
You can get a list of shipments filtered by query parameters. We introduced /search-description
on searchable resources to provide a description of the searchable fields. To look up a shipment using the parameter “Shipping error, contact support” state, for example, set the search_field
to shipment_state_id
and set the ID to 99
, which is the ID for that shipment state. (See the Shipment Status Codes table below for explanations of the various shipment states.)
Example
curl "https://api.console.yubico.com/v1/shipments_exact?search=99&search_field=shipment_state_id" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer eyJhb..."
Advanced Search
To enable advanced search, add the query string parameter &advanced_search=true
. Note that the &search
query parameters will need to respect a different structure: search=field_name::operation_type::value
. An example search with curl (--data-urlencode
is used because many characters introduced are illegal in the old query string, such as :
and |
):
curl -H "$YED_AUTHORIZATION" -G --data-urlencode 'search=shipment_request_date::range::2020-05-10T00:00:00Z|2020-12-10T00:00:00Z' --data-urlencode 'search=organization_name::like::alpha comp' --data-urlencode 'search=organization_name::exact::demo_org' 'http://api.console.local/v1/shipments_exact?offset=0&limit=10&sort_by=shipment_request_date&sort_direction=DESC&advanced_search=true'
This is the encoded URL.
GET /v1/shipments_exact?offset=0&limit=10&sort_by=shipment_request_date&sort_direction=DESC&advanced_search=true&search=shipment_request_date%3A%3Arange%3A%3A2020-05-10T00%3A00%3A00Z%7C2020-12-10T00%3A00%3A00Z&search=organization_name%3A%3Alike%3A%3Aalpha%20comp&search=organization_name%3A%3Aexact%3A%3Ademo_org HTTP/1.1
Fields with different names will be searched in an AND, while fields with the same name will be ORed, so the resulting query fragment will be:
WHERE (shipment_request_date BETWEEN ? AND ?) AND ((organizations.organization_name = ?) OR (organizations.organization_name LIKE ?)) ORDER BY shipment_request_date DESC LIMIT ?
with the following array to fill in the ?
in the fragment:
[2020-05-10 00:00:00 +0000 UTC 2020-12-10 00:00:00 +0000 UTC demo_org %alpha comp% 10]
Note
The old search will continue to work as before.
Filtering and Pagination
Refer to the API docs for the GetShipmentsExact operation .
Status
Shipment Status Codes
At any of the states between 1 and 9, a shipment request can be edited. From this point on, a shipment request is either processed through to an end state, or set back to state 99.
For information on how address validation affects the success of a shipping request, see the Troubleshooting chapter.
This table is very wide; scroll horizontally to see all four columns.
shipment_state_id | shipment_state_code | shipment_state_description | shipment_state_message |
---|---|---|---|
1 | ShipmentStateIncomplete | Shipment request received
by YubiEnterprise Delivery
system but contained some
data that could not be
processed.
(2), (3) |
Incomplete Shipping Request |
2 | ShipmentStateDraft | Shipment request is being
edited and is not ready for
processing.
|
Draft |
3 | ShipmentStateAwaitingValidation | Shipment request received,
no validation done yet.
|
Awaiting Validation |
4 | ShipmentStateProcessingAddress | Shipment request locked as
it undergoes country check,
address validation, sales
tax rate lookup (US), DPL
check.
|
Processing |
5 | ShipmentStateAddressValid | Shipment request address has
been validated, ready to be
picked up by fulfillment
processor.
|
Accepted for Fulfillment |
6 | ShipmentStateAddressInvalid | Shipment request address is
invalid but an alternative
address has been found and
suggested.
(2), (3) |
Incomplete |
7 | ShipmentStateAddressFail | Shipment request address
could not be validated and
no alternative could be
found for suggesting.
(2), (3) |
Address is undeliverable
or could not be
understood
|
8 | ShipmentStateError | Shipment request has failed
processing due to
insufficient credits
or insufficient inventory.
|
Error: Processing Error,
contact Support
|
9 | ShipmentStateDPLMatch | Shipment request recipient
found on DPL, therefore it
is illegal to fulfill this
shipment request.
(4) |
Error: DPL Match |
99 | ShipmentStateShipmentError | Shipment request rejected
from ShipmentState-
ProcessingFulfillment
with “%s” error message;
could not be fulfilled by
processor.
|
Error: Shipping error,
contact Support
|
100 | ShipmentStateProcessingShipment | Shipment request was locked
at 1000hrs UTC to calculate
and deduct tax, inventory,
and credits.
(1) |
Processing: Inventory &
Tax Deductions
|
101 | ShipmentStateFulfillmentReady | Shipment request ready to be
queued for fulfillment.
|
Processing: Ready for
Fulfillment
|
102 | ShipmentStateProcessingFulfillment | Shipment sent for fulfill-
ment at 10:00am (or cutoff
time).
(1) |
Processing: Sent for
Fulfillment
|
103 | ShipmentStateShipped | Shipment sent out by
fulfillment processor and is
in transit.
|
Shipped: In transit |
104 | ShipmentStateDelivered | Shipment delivered. | Delivered |
105 | ShipmentStateLost | Shipment lost and delivery
is no longer expected.
|
Shipment Lost/Missing |
106 | ShipmentStateDeliveryException | Customs hold or undelivered
or returned shipment to
sender or any other shipping
exceptions.
|
Delivery Exception |
1025 | ShipmentStateShippingQueue | Shipment queued for
fulfillment.
|
Processing:
Queued for Fulfillment
|
2000 | ShipmentStateManualFulfillment | Shipment is being fulfilled
manually. No further action
by shipment requestor is
required.
|
Manual Processing |
(1)
Refer to Timing for cutoff times.
(2)
Incomplete Address: Secondary line information such as apartment (apt), suite, unit is missing. Therefore it is not possible to guarantee delivery to the correct recipient.
(3)
Address is Undeliverable or could not be understood: The address is either not physically deliverable or it could not be resolved to a real location.
(4)
Any shipping request with a recipient name and/or address found on the US government’s DPL (Denied Parties/Persons List) cannot be fulfilled.
Shipment Status Messages
Scroll horizontally to see the entire width of the table.
As the following table is wide, you may need to scroll horizontally. In the Explanation column, the source of the message is given: YubiEnterprise Delivery system for internal messages, US Validation for the US Postal Service, and finally, International Validation. Messages originating from the last two are simply passed on to you by YubiEnterprise Delivery.
Message | Explanation |
---|---|
InventoryProductId not specified for ProductId %d - ShipmentStateError |
YubiEnterprise Delivery system
|
Too many keys in shipment - TotalKeysShipped %d > %d - ShipmentStateError | YubiEnterprise Delivery system
|
Not enough Inventory for Shipment - ShipmentStateError | See Purchase Orders
YubiEnterprise Delivery system
|
Re-enter the address differently; some parts of it are invalid. See
the YubiEnterprise documentation for more guidance.
|
See Troubleshooting
US Validation
|
The address is invalid. See the YubiEnterprise documentation for more
guidance.
|
See Troubleshooting
US Validation
|
The address is valid. | No further explanation required
US Validation
|
Remove the ‘secondary unit designator’ (apt, suite, department, etc.)
because it is superfluous.
|
Remove the apartment number, unit, etc.:
it is considered wrong or unnecessary
US Validation
|
Enter second line information (apartment, unit, etc.).
The information in the primary line is not specific enough.
|
Add the apartment number, unit, etc.
US Validation
|
The address is a valid military address. | No further explanation required
US Validation
|
The address is a valid General Delivery address where individuals without
permanent addresses can receive mail.
|
No further explanation required
US Validation
|
The address is valid. An organization such as a government agency can
can have its own zipcode because it receives a large volume of mail.
|
No further explanation required
US Validation
|
Enter a street number; for example, for Yubico ‘Lytton Ave’ alone is not
sufficient, it needs to be ‘530 Lytton Ave’.
|
The number on the primary line, e.g., the
“185” in “185 Berry Street” is missing
|
Enter a valid street number. | The number on the primary line, e.g., the
“185” in “185 Berry Street” is not valid
US Validation
|
Enter a PO Box, Rural Route, or Highway Contract box number. | US Validation
|
Enter a valid PO Box, Rural Route, or Highway Contract box number. | US Validation
|
Enter the Private Mailbox (PMB) identifier or the # sign, followed by the
PMB number.
|
PMB number is Private Mailbox Number
US Validation
|
This address is not eligible to receive mail. | US Validation
|
The address is that of a Commercial Mail Receiving Agency (CMRA) a private
business that accepts mail for recipients, and the required private
mailbox information is present.
|
US Validation
|
The address is missing some important secondary line information
(apartment, unit, etc).
|
No further explanation required
International Validation
|
Mail is unlikely to arrive at this destination - please verify input. | No further explanation required
International Validation
|
This street could not be found within the city or postal code. | No further explanation required
International Validation
|
Invalid OrganizationId for Shipment | YubiEnterprise Delivery system |
Country Code not set for Shipment | YubiEnterprise Delivery system |
Country could not be found from CountryCode2: %s | Country code entered is not in
YubiEnterprise Delivery system list
|
Shipment has no shipment items | YubiEnterprise Delivery system |
DeliveryType not set for Shipment, defaulting to 1 - normal | YubiEnterprise Delivery system |
Invalid DeliveryType %s for Shipment | YubiEnterprise Delivery system |
InventoryType not set for Shipment, defaulting to 1 | YubiEnterprise Delivery system |
InventoryType %s not valid set for Shipment | You cannot use this InventoryType for this
shipment - YubiEnterprise Delivery system
|
Negative quantity entered for ShipmentItem with ProductId=%d defaulting to 0 | You set the quantity of the specified
ProductID to be shipped to less than zero.
YubiEnterprise Delivery system
|
Invalid ShipmentProductQuantity for ShipmentItem %d | You probably do not have sufficient
inventory - YubiEnterprise Delivery system
|
Invalid ShipmentProductLineCost for ShipmentItem %d | YubiEnterprise Delivery system |
Invalid Shipment - Total keys in shipment greater than 500 | You cannot ship more than 500 items at
once - YubiEnterprise Delivery system
|
Shipment has zero total item quantity | The number of items to be shipped must be
> than 0 - YubiEnterprise Delivery system
|
US Address is missing the state name/abbreviation in region field | No further explanation required
YubiEnterprise Delivery system
|
Bad ProductId in ShipmentProduct for NewShipmentProduct | ProductID is wrongly specified or invalid
YubiEnterprise Delivery system
|
Input for %s exceeded limit of %d characters | Specified field cannot accept the number
of characters that were entered.
YubiEnterprise Delivery system
|
Shipment of these products to this country using this delivery type is
not supported. For more information, see Delivery Policies.
|
Shipment request contravenes one or more
business rules. YubiEnterprise Delivery
system.
|
- See the USPS FAQ.
Response Request Status Codes
The responses to your requests indicate what is happening on the server side. Below are the common status codes in responses from the YubiEnterprise Delivery API, and what they mean.
Code | Meaning | Explanation |
---|---|---|
200 | OK | The request was successful and the response
body contains the representation requested
|
302 | FOUND | A common redirect response; this will
redirect to the OAUTH login page
|
400 | BAD REQUEST | API validation failed for the request |
403 | FORBIDDEN | API denied permission to fulfill the
requested resource
|
404 | NOT FOUND | The requested resource was not found |
Users, Roles, and Organizations
Since API tokens are scoped to organizations, if an organization is shipping YubiKeys to both United States/Canada and to Europe, two API tokens are required: one for the US/CAN organization and one for the European organization.
An individual user can have one role in one organization and the same or a different role in another organization; for example, user Jan could be an owner in a company’s US/CAN organization and an Admin in the same company’s EU organization. However, because these are separate organizations, if Jan is logged in to the US/CAN YubiEnterprise, Jan cannot use that login to perform operations in the company’s EU YubiEnterprise.
Because it is possible to change the role of a user already in an organization, it is worth noting that deleting a user both:
- Deletes that user’s association with the organization, and
- Removes from that user the permissions associated with their role.
It is therefore possible in theory (though undesirable) for a user to be a member of an organization without having a role.
To file a support ticket for YubiEnterprise Delivery, click Support.