/api/auth/login
Create an API token
Send an email and password. The demo owner account is [email protected] with password password.
{
"email": "[email protected]",
"password": "password"
}
Foundation endpoints for token auth, operational identity, clients, locations, and last-mile parcels.
/api/auth/login
Send an email and password. The demo owner account is [email protected] with password password.
{
"email": "[email protected]",
"password": "password"
}
/api/auth/me
Requires Authorization: Bearer {token}. Returns user, organization, location, and roles.
/api/auth/logout
Requires Authorization: Bearer {token}. Deletes the token used for the request.
/api/roles
Owner/admin only. Returns the seeded Spatie roles such as admin, dispatcher, pickup_point_staff, client_admin, and client_user.
/api/clients
Owner/admin only. Supports optional is_active and search filters. Results are scoped to the authenticated user's organization.
/api/clients
Creates a customer/merchant record inside the authenticated organization. Slugs are unique per organization.
{
"name": "Demo Merchant",
"slug": "demo-merchant",
"contact_name": "Merchant Admin",
"contact_email": "[email protected]"
}
/api/users
Owner/admin only. Supports optional role, location_id, client_id, and search filters.
/api/users
Operational users have client_id = null. Client users require client_id. Pickup point staff require location_id.
{
"name": "Pickup Staff",
"email": "[email protected]",
"password": "password",
"location_id": 5,
"roles": ["pickup_point_staff"]
}
/api/users/{user}
Owner/admin only. Keeps organization, location, client, and role assignments consistent with the access model.
shipbee:demo populate
Adds deterministic demo clients, staff users, pickup point users, locations, parcels, barcodes, parcel events, and location inventory movements.
./vendor/bin/sail artisan shipbee:demo populate
shipbee:demo clear
Removes the deterministic scenario records while keeping base countries, roles, the demo organization, and the base admin/merchant accounts.
./vendor/bin/sail artisan shipbee:demo clear
/api/countries
Requires Authorization: Bearer {token}. Returns seeded country records for Costa Rica, Panama, and Guatemala.
/api/countries/{code}
Country codes are two-letter ISO-style codes such as CR, PA, and GT.
/api/locations
Supports optional country_code and type filters. Results are scoped to the authenticated user's organization.
/api/locations
Allowed types are hub, warehouse, pickup_point, and crossdock. The country must match the organization country.
/api/locations/{location}
Locations are not deleted in this foundation; use is_active to disable them.
/api/locations/{location}/parcels
Staff-only endpoint. Returns parcels where current_location_id matches the location. Supports status, delivery_method, barcode, and client_id filters.
/api/locations/{location}/movements
Returns incoming and outgoing parcel movements for the location. Supports type, parcel_id, barcode, date_from, and date_to filters.
/api/locations/{location}/inventory-summary
Returns current parcel count, incoming today, outgoing today, ready for pickup count, and picked up today count.
/api/parcels
Returns paginated results. Supports page, per_page up to 100, and filters for status, tracking_number, barcode, country_code, current_location_id, handover_method, delivery_method, and pickup_point_id.
/api/parcels
Creates a last-mile parcel with separate handover and delivery methods. Staff users may provide client_id; client users are always assigned to their own client. ShipBee generates tracking_number and a default system barcode when omitted; integrations that print their own labels may still provide optional tracking_number and barcodes.
{
"handover_method": "pickup_requested",
"pickup_requested_at": "2026-05-12 10:00:00",
"delivery_method": "home_delivery",
"recipient_name": "Maria Perez",
"recipient_phone": "+506 2222 3333",
"delivery_address_line_1": "Avenida Central 100",
"delivery_city": "San Jose",
"delivery_country_code": "CR"
}
/api/parcels/{parcel}/labels/pdf
Returns a browser-printable 4x6 PDF label for an accessible parcel. The parcel response includes this URL at labels.pdf_url.
curl "https://api.ship.jorkvist.com/api/parcels/142/labels/pdf" \
-H "Authorization: Bearer {token}" \
-o shipbee-label.pdf
/api/parcels/{parcel}/labels/zpl
Returns a raw 203dpi Zebra ZPL label for the same 4x6 layout. The parcel response includes this URL at labels.zpl_url.
curl "https://api.ship.jorkvist.com/api/parcels/142/labels/zpl" \
-H "Authorization: Bearer {token}" \
-o shipbee-label.zpl
/api/parcels/{parcel}/receive
Sets received_at, received_location_id, and current_location_id. The receiving location must have can_receive_parcels enabled and the action writes a parcel_received event.
/api/parcels/{parcel}
Updates non-destination fields only. Recipient, delivery method, home delivery address, and pickup point changes must use the explicit action endpoints so timeline events are always recorded.
/api/parcels/{parcel}/change-delivery-address
Allowed only for home_delivery parcels. Updates the parcel delivery snapshot and creates a delivery_address_changed event with old and new address metadata.
/api/parcels/{parcel}/change-pickup-point
Requires a pickup point location in the authenticated user's organization. Updates pickup_point_id, sets delivery_method to pickup_point, and creates a pickup_point_changed event.
/api/parcels/{parcel}/change-delivery-method
Supports home_delivery to pickup_point and pickup_point to home_delivery. Creates a delivery_method_changed event.
/api/parcels/{parcel}/change-recipient
Updates recipient snapshot fields and creates a recipient_changed event with old and new recipient metadata.
/api/parcels/{parcel}/status
Updates parcel status through the allowed transition map. Status changes write status_changed events with old/new state and optional metadata.
/api/parcels/{parcel}/events
Returns the parcel timeline with event_type, occurred time, old values, new values, metadata, status transition fields, user, and location fields.
/api/parcels/{parcel}/comments
Stores operational notes for the parcel without adding customs or inspection workflows.
/api/pickup/parcels
Staff-only endpoint for the currently logged-in organization. Returns pickup point parcels that are already ready_for_pickup and physically at their assigned pickup point. Pickup point staff are automatically limited to their assigned location_id.
Optional filters: pickup_point_id, client_id, barcode, and pickup_code. The barcode filter matches either the parcel tracking_number or a related barcode record.
GET /api/pickup/parcels?pickup_point_id=5&barcode=SB-CR-000142
Authorization: Bearer {token}
{
"data": [
{
"id": 142,
"organization_id": 1,
"client_id": 3,
"country_code": "CR",
"current_location_id": 5,
"delivery_method": "pickup_point",
"pickup_point_id": 5,
"pickup_point_location_id": 5,
"pickup_code": "482913",
"pickup_code_generated_at": "2026-05-16T15:04:22.000000Z",
"pickup_code_expires_at": "2026-05-30T15:04:22.000000Z",
"pickup_ready_at": "2026-05-16T15:04:22.000000Z",
"picked_up_at": null,
"picked_up_by_name": null,
"tracking_number": "SB-CR-000142",
"status": "ready_for_pickup",
"recipient_name": "Maria Perez",
"recipient_phone": "+506 2222 3333",
"recipient_email": "[email protected]",
"delivery_address": {
"line_1": "Avenida Central 100",
"line_2": null,
"city": "San Jose",
"state": null,
"postal_code": null,
"country_code": "CR",
"latitude": null,
"longitude": null,
"instructions": "Ask for ID before handover."
},
"pickup_point": {
"id": 5,
"name": "Alajuela Pickup",
"code": "ALA-PUP",
"type": "pickup_point",
"city": "Alajuela",
"can_be_pickup_point": true
},
"barcodes": [
{
"id": 201,
"parcel_id": 142,
"barcode": "SB-CR-000142",
"type": "primary"
}
]
}
]
}
/api/pickup/scans/receive
Scans a pickup parcel into a pickup-point-capable location. The parcel must use delivery_method = pickup_point and be assigned to the submitted location_id. The action generates a 6-digit pickup_code if one does not already exist, sets pickup_ready_at, and marks the parcel ready_for_pickup.
Required body fields: barcode and location_id. Pickup point staff may only receive into their assigned location. Optional geolocation stores the event coordinates in parcel event and movement metadata; include latitude and longitude, with optional accuracy_meters and captured_at.
{
"barcode": "SB-CR-000142",
"location_id": 5,
"geolocation": {
"latitude": 9.932542,
"longitude": -84.079578,
"accuracy_meters": 12.5,
"captured_at": "2026-05-16T15:04:20Z"
}
}
{
"data": {
"id": 142,
"current_location_id": 5,
"delivery_method": "pickup_point",
"pickup_point_id": 5,
"pickup_code": "482913",
"pickup_code_generated_at": "2026-05-16T15:04:22.000000Z",
"pickup_code_expires_at": "2026-05-30T15:04:22.000000Z",
"pickup_ready_at": "2026-05-16T15:04:22.000000Z",
"picked_up_at": null,
"tracking_number": "SB-CR-000142",
"status": "ready_for_pickup",
"recipient_name": "Maria Perez",
"pickup_point": {
"id": 5,
"name": "Alajuela Pickup",
"code": "ALA-PUP",
"type": "pickup_point",
"can_be_pickup_point": true
},
"events": [
{
"event_type": "arrived_at_pickup_point",
"location_id": 5,
"metadata": {
"pickup_point_id": 5,
"geolocation": {
"latitude": 9.932542,
"longitude": -84.079578,
"accuracy_meters": 12.5,
"captured_at": "2026-05-16T15:04:20Z"
}
}
},
{
"event_type": "pickup_code_generated",
"location_id": 5,
"metadata": {
"pickup_code": "482913",
"pickup_point_id": 5,
"geolocation": {
"latitude": 9.932542,
"longitude": -84.079578,
"accuracy_meters": 12.5,
"captured_at": "2026-05-16T15:04:20Z"
}
}
},
{
"event_type": "ready_for_pickup",
"location_id": 5,
"metadata": {
"pickup_point_id": 5,
"geolocation": {
"latitude": 9.932542,
"longitude": -84.079578,
"accuracy_meters": 12.5,
"captured_at": "2026-05-16T15:04:20Z"
}
}
}
]
}
}
/api/pickup/scans/handover
Hands a ready pickup parcel to the consignee. Submit either barcode or pickup_code, plus the pickup point and consignee handover details. The parcel must be ready_for_pickup at the submitted pickup_point_id.
Required body fields: pickup_point_id, picked_up_by_name, and either barcode or pickup_code. Optional: picked_up_by_document and geolocation. On success the action stores the handover details, sets picked_up_at, clears current_location_id, marks the parcel picked_up, and stores event coordinates in parcel event and movement metadata.
{
"pickup_code": "482913",
"pickup_point_id": 5,
"picked_up_by_name": "Maria Perez",
"picked_up_by_document": "CR-01-1234-0567",
"geolocation": {
"latitude": 9.93612,
"longitude": -84.08364,
"accuracy_meters": 8
}
}
{
"data": {
"id": 142,
"current_location_id": null,
"delivery_method": "pickup_point",
"pickup_point_id": 5,
"pickup_code": "482913",
"pickup_ready_at": "2026-05-16T15:04:22.000000Z",
"picked_up_at": "2026-05-16T16:18:09.000000Z",
"picked_up_by_name": "Maria Perez",
"picked_up_by_document": "CR-01-1234-0567",
"picked_up_by_user_id": 12,
"tracking_number": "SB-CR-000142",
"status": "picked_up",
"recipient_name": "Maria Perez",
"events": [
{
"event_type": "pickup_code_verified",
"location_id": 5,
"metadata": {
"pickup_code": "482913",
"pickup_point_id": 5,
"verification_method": "pickup_code",
"geolocation": {
"latitude": 9.93612,
"longitude": -84.08364,
"accuracy_meters": 8
}
}
},
{
"event_type": "parcel_picked_up",
"location_id": 5,
"metadata": {
"picked_up_by_name": "Maria Perez",
"pickup_point_id": 5,
"geolocation": {
"latitude": 9.93612,
"longitude": -84.08364,
"accuracy_meters": 8
}
}
}
]
}
}
{
"token": "...",
"user": {
"id": 1,
"organization_id": 1,
"location_id": 1,
"client_id": null,
"name": "ShipBee Admin",
"email": "[email protected]"
},
"organization": {
"id": 1,
"name": "ShipBee Costa Rica",
"slug": "shipbee-cr",
"country_code": "CR",
"timezone": "America/Costa_Rica",
"currency_code": "CRC",
"is_active": true
},
"location": {
"id": 1,
"organization_id": 1,
"country_code": "CR",
"name": "San José Hub",
"code": "SJO-HUB",
"type": "hub",
"city": "San José",
"is_active": true
},
"roles": ["owner"]
}
users.client_id is nullclient_id when creating parcelsusers.client_id is setorganization_id is operational ownershipclient_id is customer ownership