.. _api-shipment-request: ======================== API Shipment Requests ======================== .. include:: includes/bulk-api-deprecation-note.rst Before starting, it is recommended that you review the information in :ref:`requesting-shipment-label` which also applies to executing shipment requests with the API (as well as to the other methods for making shipment requests). Using the API you can make individual shipment requests or you can make shipment requests in bulk. This latter method requires the CSV file. Many of the necessary parameters are shared by the two methods. Instructions for filling out the shared fields as the system expects are set out below in the lettered sections (corresponding to the columns in the CSV file), whereas the general instructions for individual and bulk requests are set out in separate sections. Verify Inventory Before Requesting Shipment =========================================== 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`` is ``1``, 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. .. _inv-ex-label: ``/inventory`` Example Output ----------------------------- .. code-block:: Json { "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] } ] } Individual Shipment Requests via API ==================================== 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. .. LAAS-2648 .. important:: Starting with release 2.8.0, the ``street_line3`` field in the recipient address information will be deprecated and will only be available until September 2024. There is no replacement API for this functionality. Example: 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: .. code-block:: Json { "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: 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: .. code-block:: Json { "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 } ] } 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-request-sample: 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: .. code-block:: Bash 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 ------------------------------ .. code-block:: Json { "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 } .. _multiple-label: Shipping Products to Multiple Addresses ======================================= .. include:: includes/bulk-api-deprecation-note.rst 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. .. code-block:: Bash #!/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 :ref:`shipping-multiple-label`. Validating CSV Uploads ---------------------- .. table:: +--------------+---------------------------------------------+ |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 Bulk Shipment Requests via API ============================== .. include:: includes/bulk-api-deprecation-note.rst Bulk orders using the API are still handled through the following APIs: * ``GET /shipments/bulk`` * ``POST /shipments/bulk`` * ``POST /shipments/bulkvalidate`` * ``POST /shipments/bulkdelete`` 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, download the template file each time you prepare to upload a new batch of shipment requests. Shipment Request Fields in CSV File ----------------------------------- Use the CSV file for bulk shipments via API. .. include:: includes/from-stock-specifications.rst .. include:: includes/ship-req-fields.rst C. and D. Names ---------------- .. include:: includes/name-constraints.rst E. Post Office Boxes -------------------- .. include:: includes/no-non-usa-po-boxes.rst I. Region/State --------------- .. include:: includes/usps-codes.rst L. Telephone Number ------------------- It is required 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 expressions. For ``/v1/shipments_exact`` the API validates the existence of ``recipient_telephone`` in the request body. For CSV upload via ``/v1/bulkvalidate``, the API validates the existence of ``recipient_telephone`` on each row. In both cases, 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. M. Delivery Type ------------------------ ``ShipmentDeliveryTypeEnum`` specifies the method of shipping: * 1 - Normal (standard) shipping (default) * 2 - Expedited (rush) shipping. .. _init-buffer-label: N. InventoryType ----------------- The ``inventory_type`` requires one of the values given in the *Inventory Types (Stock)* table below. .. include:: includes/InventoryTypeEnum.rst * Customers who have purchased Subscription (2.0) will be selecting only Inventory Type **3** or **5**. * 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**. * Subscription (1.0) customers: Use Inventory Types **3**, **4**, and/or **5**. .. include:: includes/init-buffer-repl.rst * 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. O. Channel Partners ------------------- To order keys via API from inventory purchased through channel partners (distributors/resellers), the new ``/shipments_exact`` APIs must be used; see :ref:`deprecated-apis-label` 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. .. _inv-prod-id-label: Product ID and Inventory Product ID -------------------------------------- The ``product_id`` is the unique identifier for the product, e.g., ``4`` is the YubiKey 5C Nano. 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 without a subscription might have only a single "bucket." Both ``product_id`` and ``inventory_product_id`` are required fields. 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 *Stock/Inventory* 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, calling ``GET /inventory`` will return a list that also contains your custom products (see also :ref:`custom-label`). * When making requests, use the ``/inventory`` end point to find the ``product_id`` to use for that and/or ``inventory_product_id``. .. Note:: The ``inventory_product_id`` **can** have the same value as the ``product_id`` field in the individual ``inventory_records``. .. table:: **Stock/Inventory: product_id and inventory_product_id mapped to Product Name** +--------------+--------------------------------------------------+ || inventory_ | | || product_id | | || and/or | | || 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 | +--------------+--------------------------------------------------+ | 68 | YubiKey C Bio - FIDO Edition | +--------------+--------------------------------------------------+ | 69 | YubiKey Bio - FIDO Edition | +--------------+--------------------------------------------------+ | 82 | Security Key NFC by Yubico (Black) | +--------------+--------------------------------------------------+ | 83 | Security Key C NFC by Yubico (Black) | +--------------+--------------------------------------------------+ | 84 | Security Key NFC by Yubico - Enterprise Edition | +--------------+--------------------------------------------------+ | 85 | Security Key C NFC by Yubico - Enterprise Edition| +--------------+--------------------------------------------------+ | 86 | Base - Standard - Primary | +--------------+--------------------------------------------------+ | 87 | Base - Standard - Backup | +--------------+--------------------------------------------------+ | 88 | Base - Standard - Primary - Replacement | +--------------+--------------------------------------------------+ | 89 | Base - Standard - Backup - Replacement | +--------------+--------------------------------------------------+ | 90 | Base - Plus - Primary | +--------------+--------------------------------------------------+ | 91 | Base - Plus - Backup | +--------------+--------------------------------------------------+ | 92 | Base - Plus - Primary - Replacement | +--------------+--------------------------------------------------+ | 93 | Base - Plus - Backup - Replacement | +--------------+--------------------------------------------------+ | 94 | Base/Bio - Standard - Primary | +--------------+--------------------------------------------------+ | 95 | Base/Bio - Standard - Backup | +--------------+--------------------------------------------------+ | 96 | Base/Bio - Standard - Primary - Replacement | +--------------+--------------------------------------------------+ | 97 | Base/Bio - Standard - Backup - Replacement | +--------------+--------------------------------------------------+ | 98 | Base/Bio - Plus - Primary | +--------------+--------------------------------------------------+ | 99 | Base/Bio - Plus - Backup | +--------------+--------------------------------------------------+ | 100 | Base/Bio - Plus - Primary - Replacement | +--------------+--------------------------------------------------+ | 101 | Base/Bio - Plus - Backup - Replacement | +--------------+--------------------------------------------------+ | 102 | Advanced - Standard - Primary | +--------------+--------------------------------------------------+ | 103 | Advanced - Standard - Backup | +--------------+--------------------------------------------------+ | 104 | Advanced - Standard - Primary - Replacement | +--------------+--------------------------------------------------+ | 105 | Advanced - Standard - Backup - Replacement | +--------------+--------------------------------------------------+ | 106 | Advanced - Plus - Primary | +--------------+--------------------------------------------------+ | 107 | Advanced - Plus - Backup | +--------------+--------------------------------------------------+ | 108 | Advanced - Plus - Primary - Replacement | +--------------+--------------------------------------------------+ | 109 | Advanced - Plus - Backup - Replacement | +--------------+--------------------------------------------------+ | 110 | Advanced/Bio - Standard - Primary | +--------------+--------------------------------------------------+ | 111 | Advanced/Bio - Standard - Backup | +--------------+--------------------------------------------------+ | 112 | Advanced/Bio - Standard - Primary - Replacement | +--------------+--------------------------------------------------+ | 113 | Advanced/Bio - Standard - Backup - Replacement | +--------------+--------------------------------------------------+ | 114 | Advanced/Bio - Plus - Primary | +--------------+--------------------------------------------------+ | 115 | Advanced/Bio - Plus - Backup | +--------------+--------------------------------------------------+ | 116 | Advanced/Bio - Plus - Primary - Replacement | +--------------+--------------------------------------------------+ | 117 | Advanced/Bio - Plus - Backup - Replacement | +--------------+--------------------------------------------------+ | 118 | Compliance - Standard - Primary | +--------------+--------------------------------------------------+ | 119 | Compliance - Standard - Backup | +--------------+--------------------------------------------------+ | 120 | Compliance - Standard - Primary - Replacement | +--------------+--------------------------------------------------+ | 121 | Compliance - Standard - Backup - Replacement | +--------------+--------------------------------------------------+ | 122 | Compliance - Plus - Primary | +--------------+--------------------------------------------------+ | 123 | Compliance - Plus - Backup | +--------------+--------------------------------------------------+ | 124 | Compliance - Plus - Primary - Replacement | +--------------+--------------------------------------------------+ | 125 | Compliance - Plus - Backup - Replacement | +--------------+--------------------------------------------------+ .. _custom-label: 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. 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``: .. code-block:: 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: .. code-block:: 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 } .. _api-bulk-shipment-deprecated-label: Deprecated APIs =============== The following tables list deprecated APIs related to shipment requests. For more information, see :ref:`deprecated-api-list-label`. .. include:: includes/deprecated-address-line3.rst .. include:: includes/api-bulk-shipment-deprecated.rst ------------------------------------- To file a support ticket for YubiEnterprise Delivery, click `Support `_.