Stores
PUT /api/vendor/v1/stores/{externalStoreId}One endpoint creates a store, updates it, attaches a fleet, and returns fleet options. It is an upsert keyed by your store id — you never need to store an id of ours.
Why PUT and not PATCH
PATCH is blocked by our edge layer and will not reach the API in production. Always send the full object with PUT.
Request
PUT /api/vendor/v1/stores/ADS-34781
Authorization: Bearer <token>
Content-Type: application/json{
"taxNumber": "1234567890",
"name": "Oncu Doner - Kizilay",
"phone": "5321234567",
"address": {
"text": "Mesrutiyet Cad. No:12/A, Kizilay, Cankaya/Ankara",
"latitude": 39.920778,
"longitude": 32.854110
},
"fleetId": "9d41c7a2-5b83-4e10-91cc-72f0ab3d5e64"
}| Field | Required | Notes |
|---|---|---|
taxNumber | yes | Identifies the branch. Used to enforce one channel per branch |
name | yes | Shown to the courier |
phone | yes | Restaurant phone, 10 digits — the courier may call it |
address.text | yes | Full address of the pickup point |
address.latitude / longitude | yes | Pickup coordinates. The courier navigates here |
fleetId | no | Omit on first call; add once the restaurant has chosen a fleet |
Response without a fleet
When fleetId is absent, the response carries the fleets that serve this address. There is no separate discovery endpoint.
{
"success": true,
"data": {
"status": "AwaitingFleet",
"subRegion": "Cankaya - Kizilay",
"availableFleets": [
{
"fleetId": "9d41c7a2-5b83-4e10-91cc-72f0ab3d5e64",
"name": "Baskent Moto Kurye",
"status": "Available",
"coverage": ["Cankaya - Kizilay", "Cankaya - Bahcelievler"],
"avgDeliveryMinutes": 27
},
{
"fleetId": "3e08b115-c6d9-4a72-8f30-1ab4c9e77d52",
"name": "Ankara Hizli Lojistik",
"status": "AtCapacity",
"coverage": ["Cankaya - Kizilay"],
"avgDeliveryMinutes": 31
}
]
}
}status of a fleet is Available, AtCapacity or Unavailable. A fleet at capacity can still be chosen — it simply is not taking new stores at this moment.
Contact details for fleets are not exposed. If the restaurant needs an introduction, ask us.
Response with a fleet
{
"success": true,
"message": "Waiting for fleet approval.",
"data": {
"status": "AwaitingFleetApproval",
"fleet": { "fleetId": "9d41...5e64", "name": "Baskent Moto Kurye" }
}
}The fleet confirms the arrangement on its side. Until then the store cannot receive orders. You get a store.activated webhook when it can.
Store status
| Status | Orders accepted | Meaning |
|---|---|---|
AwaitingFleet | no | Registered, no fleet chosen yet |
AwaitingFleetApproval | no | Fleet recorded, waiting for the fleet to confirm |
Active | yes | Operating normally |
Migrating | yes | The branch is becoming a direct Hızlıyo partner. Orders continue until the closing date |
Suspended | no | The fleet cannot currently accept orders |
Deactivated | no | Closed |
One channel per branch
A branch cannot be served by your POS and by Hızlıyo directly at the same time, nor by two integrators at once. Registration is refused when the tax number and location already belong elsewhere:
| Situation | Response |
|---|---|
| Branch is already a direct Hızlıyo partner | 409 ALREADY_HIZLIYO_PARTNER |
| Branch is registered by another integrator | 409 STORE_EXISTS_ON_ANOTHER_VENDOR |
| You already registered this branch under a different store id | 409 DUPLICATE_STORE |
Different branches of the same chain may sit in different channels — this is normal during a transition. What is not allowed is the same branch in two places.
When a restaurant moves to Hızlıyo
If a restaurant using your POS signs up with Hızlıyo directly, its store moves to Migrating rather than closing immediately. You receive store.migrating with a closing date, orders keep flowing until then, and the store closes on the earlier of: the restaurant's first order through Hızlıyo, or the end of the window.
You cannot block this transition — the restaurant chooses its channel.