Creating blueprints

Define once how orders get fulfilled and shipped, instead of per order.

Overview

A Blueprint is the policy an order is fulfilled and shipped under. Instead of every order carrying its own instructions, an order carries a blueprint_id and the blueprint decides: which facility picks it, whether it gets cartonized, whether the address is validated, what customs declaration is attached, what gets reported on.

A blueprint is a composition. It holds references to up to four component blueprints:

ComponentRequiredDecides
FulfillmentBlueprintYesWhere and how the order is picked and packed
ShippingBlueprintYesAddress validation, carrier constraints, references
AnalyticsBlueprintNoWhat is measured
CustomsBlueprintNoHow international declarations are built

Because the two required components must exist first, blueprints are built bottom-up.

Build order

  1. Fulfillment blueprint — needs a facility routing guide
  2. Shipping blueprint
  3. Optionally an analytics and/or customs blueprint
  4. The blueprint that composes them
  5. Set priority so it is selected

1. Fulfillment blueprint

mutation CreateFulfillmentBlueprint($data: FulfillmentBlueprintInput!) {
    blueprint {
        fulfillment_blueprint {
            create(data: $data) {
                id
                name
            }
        }
    }
}
{
    "data": {
        "name": "US ground fulfillment",
        "description": "Domestic orders picked from the Reno facility",
        "cartonize": true,
        "facility_routing_guide_id": "7f3a1c92-5b64-4e18-9a02-6d5c1e83b7a4",
        "generate_packslip_automatically": true
    }
}
FieldTypeRequiredNotes
nameString!Yes
descriptionString!Yes
cartonizeBoolean!YesRequires item dimensions to be useful
facility_routing_guide_idID!YesWhich facilities can fulfill, and in what order
default_priority_level_idIDNoSee priority levels below
packslip_template_idIDNo
generate_packslip_automaticallyBoolean!NoDefaults to false
pickup_location pickup_instructionsStringNoPassed through to the carrier

Priority levels

A fulfillment blueprint can carry priority levels, which order the work queue:

2. Shipping blueprint

mutation CreateShippingBlueprint($data: ShippingBlueprintInput!) {
    blueprint {
        shipping_blueprint {
            create(data: $data) {
                id
                name
            }
        }
    }
}
{
    "data": {
        "name": "Validated domestic shipping",
        "description": "Address-validated ground shipping",
        "require_address_validation": true,
        "run_address_validation_automatically": true,
        "mark_address_validated": "CHECK_ONLY",
        "parcel_reference_one_field": "external_order_id"
    }
}

The address-validation fields:

FieldDefaultEffect
require_address_validationOrders cannot ship until the address is validated
run_address_validation_automaticallytrueValidation runs on order creation rather than on demand
mark_address_validatedCHECK_ONLYWhether a passing check marks the address validated
update_address_on_validationCHECK_ONLYWhether the corrected address is written back

parcel_reference_one_field through ..._three_field name an order field whose value is printed on the label as a carrier reference — external_order_id is the usual choice.

Shipping plans

A shipping blueprint can own shipping plans, which constrain carrier and service selection:

3. Optional components

Analytics blueprints

mutation CreateAnalyticsBlueprint($data: AnalyticsBlueprintInput!) {
    blueprint {
        analytics_blueprint {
            create(data: $data) {
                id
                name
            }
        }
    }
}

Customs blueprints

A customs blueprint supplies defaults for eight shipment-level customs fields on the orders that use it. It does not build the whole declaration, and it does not read item customs data — hs_code and country_of_origin are declared per commodity on each item.

mutation CreateCustomsBlueprint($data: CustomsBlueprintInput!) {
    blueprint {
        customs_blueprint {
            create(data: $data) {
                id
                name
            }
        }
    }
}
{
    "data": {
        "name": "Standard DDP exports",
        "description": "Duties and taxes prepaid, sold goods",
        "export_reason": { "value": "SOLD", "allow_overwrite": false },
        "incoterms": { "value": "DDP", "allow_overwrite": false },
        "duties_prepaid": { "value": true, "allow_overwrite": true }
    }
}

Every one of the eight is an overwritable field — a value plus an allow_overwrite flag that defaults to false:

FieldType
commentsOverwritableStringBlueprintField
export_reasonOverwritableExportReasonBlueprintField
duties_prepaidOverwritableBooleanBlueprintField
taxes_prepaidOverwritableBooleanBlueprintField
incotermsOverwritableStringBlueprintField
usmca_appliesOverwritableBooleanBlueprintField
aes_exemptionOverwritableStringBlueprintField
itar_license_or_exemption_numberOverwritableStringBlueprintField

allow_overwrite: false means the blueprint fills the field only when the order left it unset, so a value sent on the order wins. true means the blueprint's value replaces whatever the order supplied, for that field only.

Everything else in the declaration — the exporter, importer and seller parties, declared and insured value, the commercial invoice, and the export-control blocks — is order-level only. See International orders.

4. The blueprint itself

mutation CreateBlueprint($data: BlueprintInput!) {
    blueprint {
        blueprint {
            create(data: $data) {
                id
                name
                blueprint_type
            }
        }
    }
}
{
    "data": {
        "name": "US domestic",
        "description": "Standard domestic orders",
        "fulfillment_blueprint_id": "c41d8e7b-2a96-4f53-8b17-0e9a3d62c5f8",
        "shipping_blueprint_id": "9e02b53a-7c14-4d86-a5f9-2b8710d4e36c",
        "customs_blueprint_id": null,
        "blueprint_type": "ACTIVE"
    }
}

Blueprint type

BlueprintType has three values:

ValueMeaning
ACTIVEIn use; can be selected for orders
PASSIVEExists but is not selected automatically
ERRORWhere orders land when no blueprint matches

NOTE

Keep exactly one ERROR blueprint. It is where an order goes when nothing else applies, and without it those orders have nowhere to sit.

5. Priority

Priority decides which blueprint wins when more than one could apply. Set it globally:

mutation SetGlobalPriority($priority: [BlueprintPriorityInput!]!) {
    blueprint {
        priority {
            set_global_priority(priority: $priority) {
                id
            }
        }
    }
}

Or per marketplace integration, which overrides the global order for orders from that channel:

mutation SetChannelPriority($marketplace_integration_id: ID!, $priority: [BlueprintPriorityInput!]!) {
    blueprint {
        priority {
            set_marketplace_integration_priority(marketplace_integration_id: $marketplace_integration_id, priority: $priority) {
                id
            }
        }
    }
}

Read the current order back with blueprint.global_blueprint_priority or blueprint.marketplace_integration_blueprint_priority.

Updating and deleting

Every component follows the same create / update / delete shape. The update inputs carry an id plus only the fields being changed.

WARNING

Deleting a component blueprint that a composed blueprint still references will fail. Delete top-down: the blueprint first, then its components.

Applying a blueprint per order

An order names its blueprint at creation via blueprint_id. To change it afterwards, use the order's own blueprint actions: