Courier Pickup Request

This API creates a courier pickup request for one or more consignments.

Endpoint Information

Property Value
URL {{BASE_URL}}/api/v1/pickups
HTTP Method POST
Content-Type application/json
Authentication APIKEY header
Route Name api_v1_pickups_create

Request Body Schema

{
  "appointment": {
    "start": "string (datetime)",
    "end": "string (datetime)"
  },
  "address": {
    "name": "string",
    "country_id": "integer",
    "state_id": "integer",
    "city_id": "integer",
    "street": "string",
    "postal_code": "string|null"
  },
  "consignments": [
    {
      "type": "id|barcode|reference",
      "value": "string"
    }
  ]
}

Request Parameters

appointment

Field Type Required Description
start Datetime String REQUIRED Pickup start time
end Datetime String REQUIRED Pickup end time

address

Field Type Required Description
name String REQUIRED Address label/name (e.g., "Main Warehouse")
country_id Integer REQUIRED Country ID
state_id Integer REQUIRED State/province ID
city_id Integer REQUIRED City/district ID
street String REQUIRED Address line
postal_code String Optional Postal code

consignments[]

Field Type Required Description
type Enum String REQUIRED Matching type. Allowed values: id, barcode, reference
value String REQUIRED Value for the selected matching type

Validation Rules

Structural and required field rules

  • appointment, address, and consignments are required.
  • consignments must include at least 1 item.
  • consignments[*].type can only be id, barcode, or reference.
  • consignments[*].value cannot be empty.
  • address.name and address.street cannot be empty.
  • country_id, state_id, and city_id must be integers.

Length rules

  • address.name maximum length: 255 characters.
  • address.street maximum length: 255 characters.
  • address.postal_code maximum length: 20 characters.

Date/time rules

  • appointment.start and appointment.end must be parseable datetime values (recommended: ISO 8601 / RFC3339).
  • appointment.end must be greater than appointment.start.
  • Appointment window must be at least 30 minutes.
  • appointment.end cannot be in the past.
  • appointment.start must be at least about 1 hour in the future.

Example Usage

API Request

curl --location '{{BASE_URL}}/api/v1/pickups' \
  --header 'APIKEY: {{APIKEY}}' \
  --header 'Content-Type: application/json' \
  --data '{
    "appointment": {
      "start": "2026-03-28T10:00:00+03:00",
      "end": "2026-03-28T12:00:00+03:00"
    },
    "address": {
      "name": "Acme Warehouse",
      "country_id": 223,
      "state_id": 34,
      "city_id": 1,
      "street": "Maslak Mah. Buyukdere Cad. No:100",
      "postal_code": "34485"
    },
    "consignments": [
      {
        "type": "barcode",
        "value": "C2H000123456"
      }
    ]
  }'

Successful Response

HTTP Status: 201 Created

{
  "status": true,
  "message": "Pickup request created successfully.",
  "data": {
    "id": 1452,
    "tracking_number": "PCK-20260328-0001452",
    "customer": {
      "id": 17,
      "name": "Acme Logistics Inc."
    },
    "status": "scheduled",
    "appointment": {
      "start": "2026-03-28T10:00:00+03:00",
      "end": "2026-03-28T12:00:00+03:00",
      "is_past": false
    },
    "address": {
      "name": "Acme Warehouse",
      "country": {
        "id": 223,
        "code": "TR",
        "name": "Turkey",
        "iso2": "TR",
        "iso3": "TUR"
      },
      "state": {
        "id": 34,
        "name": "Istanbul",
        "stateCode": "34",
        "country": {
          "id": 223
        }
      },
      "city": {
        "id": 1,
        "name": "Sisli",
        "state": {
          "id": 34
        },
        "country": {
          "id": 223
        }
      },
      "address": "Maslak Mah. Buyukdere Cad. No:100",
      "formatted": "Maslak Mah. Buyukdere Cad. No:100, Sisli/Istanbul",
      "postalCode": "34485",
      "stateName": "Istanbul",
      "cityName": "Sisli"
    },
    "consignments": [
      {
        "id": 9988,
        "barcode": "C2H000123456",
        "reference_number": "REF-1001",
        "desi": 3.5,
        "weight": 2.1,
        "status": "pending",
        "tracking_code": null,
        "drop_off_event_at": null
      }
    ],
    "statistics": {
      "total_consignments": 1,
      "dropped_off_count": 0,
      "pending_count": 1,
      "progress_percentage": 0
    },
    "created_at": "2026-03-27T11:15:42+03:00",
    "updated_at": "2026-03-27T11:15:42+03:00"
  }
}

Error Responses

Error response format:

{
  "status": false,
  "errors": [
    {
      "message": "string",
      "field": "string|null"
    }
  ]
}

400 - Validation Error (Example)

{
  "status": false,
  "errors": [
    {
      "message": "pickup.validation.appointment_end_after_start",
      "field": "appointment.end"
    },
    {
      "message": "pickup.validation.country_integer",
      "field": "address.countryId"
    }
  ]
}

400 - Domain Rule Error (Example)

{
  "status": false,
  "errors": [
    {
      "message": "Appointment window must be at least 30 minutes"
    }
  ]
}

401 - Authentication Error (Example)

{
  "status": false,
  "errors": [
    {
      "message": "Invalid credentials"
    }
  ]
}

404 - Consignment Not Found (Example)

{
  "status": false,
  "errors": [
    {
      "message": "Consignment not found with barcode: C2H000123456"
    }
  ]
}

Example Scenarios

Scenario 1: Creating pickup for a single consignment by barcode

  • Use one item in the consignments list.
  • Send type = "barcode" and value = "{barcode}".
  • On success, the API returns 201 Created.

Scenario 2: Creating pickup for multiple consignments with mixed identifiers

  • Send multiple items in the consignments list.
  • Each item can use a different type (id, barcode, reference).
  • The system validates all consignments and creates one pickup request.