Shipping addresses
Where a customer’s goods go, as a resource of its own: any number of addresses per customer, each with a recipient that is independent of the customer you bill.
Why this matters
A customer has one billing address, and that is rarely where the parcel goes. Goods are delivered to a site, a warehouse, a department or an employee’s home, and the person receiving them is not the person who pays. Keeping that on the customer means one address, one name and no way to say which site an order is for.
A shipping address is therefore a top-level resource with its own identifier, reference and lifecycle, linked to a customer by customer_id. A customer can hold as many as you need, one of them marked as the default.
Create an address
An address is created DRAFT. reference, customer_id, recipient and address are required; customer_id is immutable afterwards, so an address cannot be moved to another customer.
The recipient is not the customer
recipient describes who the parcel is addressed to, which is why it carries its own contact details rather than reusing the customer’s.
The two sub-objects are mutually exclusive. Sending individual on an ORGANIZATION recipient is refused with recipient.individual, and organization on an INDIVIDUAL recipient with recipient.organization, so a recipient can never carry a company and a person at the same time.
INDIVIDUAL is what you want for delivery to an employee’s home address. The customer stays the company you invoice, and the parcel is addressed to the person.
The lifecycle
POST /v1/shipping-addresses/{id}/activate moves a DRAFT address to ACTIVE, and POST /v1/shipping-addresses/{id}/deprecate retires an ACTIVE one. A DELETE removes an address that is DRAFT or DEPRECATED, which keeps an address that is live from disappearing under an order that references it.
The default address
One address per customer can be the default, for the case where a request names a customer but no address.
Only an ACTIVE address can be the default, and setting one clears the flag on the address that held it, so a customer never has two. Deprecating the default clears the flag without choosing a successor: a customer can be left with no default, and your integration should handle that rather than assume one exists.
Find an address
GET /v1/shipping-addresses lists them, with customer_id to narrow to one customer and the repeatable statuses[] to leave out the addresses you retired.
A single address is read with GET /v1/shipping-addresses/{id}, which takes the id or the reference, as do PATCH and DELETE and the three actions.
Keep a system of record in sync
PUT /v1/shipping-addresses upserts on reference: it creates the address when the reference is new and updates it when it is not. An ERP or order system that already owns these addresses can therefore replay its own records without first asking whether Solvimon has seen them, and without keeping a map of Solvimon ids.
Edge cases
- The endpoints need the
SHIPPING_ADDRESSpermissions:VIEWto read and list,CREATEto create,UPDATEto patch and to run the three actions, andDELETEto delete. The upsert needsCREATEandUPDATEtogether. PATCHcannot changecustomer_id. Create a new address under the right customer instead.- Deleting is only for addresses that were never used or have been retired. Deprecate an
ACTIVEaddress rather than trying to delete it. - Shipping addresses are API-only for now; there is no screen for them in Desk.