Open API

Импорт на поръчки в Agility

Използвайте store-scoped API ключ и POST /orders/import — поръчките влизат директно в таблото.

Base URL

https://www.agility.bg/api/v1

Endpoint

POST /orders/import

Limit

500 orders/request

Общ преглед

Как работи

1. Създавате ключ

Ключът е вързан към конкретен магазин и приема данни само за него.

2. Изпращате поръчки

Външната система прави POST към /orders/import с масив `orders` (до 500).

3. Поръчките са в Agility

Поръчките минават през pipeline-а (валидация, адреси/офиси) и влизат в таблото веднага.

Бърз старт

  1. 1От таблото отворете Настройки → Синхронизиране на поръчки.
  2. 2Запазете секрета. Показва се само при създаване.
  3. 3Изпратете поръчки към POST /orders/import с Bearer token за директен импорт.

Authentication

API ключ

Всяка заявка трябва да съдържа store-scoped ключ в `Authorization` header. Отменени или невалидни ключове връщат `401`. При създаване можете да ограничите правата (scopes).

HTTP header
Authorization: Bearer agl_live_ВАШИЯТ_КЛЮЧ

Scopes (права)

Подразбиране е пълен достъп `*`. Можете да създадете ключ само с нужните права:

  • `orders:write` — POST /orders/import, /orders/database, /orders/cancel
  • `orders:read` — GET /orders/courier-status (`orders:write` също го покрива)
  • `database:sync` — POST /orders/sync/database (+ `importToAgility`)
  • `integration:read` — GET /integration
  • Липсващ scope → `403`.

Endpoint

POST /orders/import

Директно в Agility

Директен импорт в Agility: валидация, мачване на адреси/офиси и запис в магазина. AgilityAI Engine е включен по подразбиране за Speedy BG/RO и Еконт BG — попълва град и site/city id при `siteStatus`/`VALID`; при `competingOfficeIds` иска избор на офис; прилага bookable ids при `engineStatus`/`VALID`/`autoValidBlocked`; при `destinationStatus`/`INVALID` иска по-добър адрес; несигурният `REVIEW_REQUIRED` остава за преглед. Изключва се с `useAddressResolver: false`.

MethodPOSTURLhttps://www.agility.bg/api/v1/orders/importBody{ orders: [...] }

Endpoint

POST /orders/cancel

Анулация

Анулира поръчка в Agility по външен `code` (или `id`). При Speedy товарителница преди вземане първо се анулира в Спиди. При отказ от Спиди поръчката остава активна. Еконт се анулира само локално.

MethodPOSTURLhttps://www.agility.bg/api/v1/orders/cancelBody{ code, comment }
curl — /orders/cancel
curl -s -X POST \
  -H "Authorization: Bearer agl_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"code":"1024","comment":"Customer requested cancellation"}' \
  https://www.agility.bg/api/v1/orders/cancel
200 response
{
  "ok": true,
  "order": {
    "code": "1024",
    "status": "cancelled",
    "courier": "Speedy",
    "waybill": "1234567890",
    "deliveryType": "to_address"
  },
  "speedyCancel": "success"
}

Endpoint

GET /orders/courier-status

Куриерски статус

Read-only: връща статуса на поръчката както е записан в Agility (Спиди или Еконт). Без live заявка към куриера. Query: `code` или `id`.

MethodGETURLhttps://www.agility.bg/api/v1/orders/courier-status?code=1024Querycode | id
curl — /orders/courier-status
curl -s -X GET \
  -H "Authorization: Bearer agl_live_YOUR_KEY" \
  "https://www.agility.bg/api/v1/orders/courier-status?code=1024"
200 response
{
  "ok": true,
  "order": {
    "code": "1024",
    "status": "sent",
    "courier": "Speedy",
    "waybill": "1234567890",
    "deliveryType": "to_office"
  }
}

Reference

Payload fields

Body за `/orders/import`: опционално `useAddressResolver` и масив `orders`. Полетата по-долу са Shopify-съвместими; приемат се и snake_case alias-и (`order_code`, `customer_phone`, `cod_fee`…). Опционални са `COD Fee`, `Additional Names` и `Additional Prices`. `Subtotal` е без доставка; `Total` включва доставка, такса НП и допълнителни услуги, когато ги има. Има лимити за дължина на полетата (напр. адрес до 2000 символа, до 80 line items).

Namerequired

Unique order number (`order_code`). Rows with the same value in one request are grouped as one order. On `POST /orders/import`, if this code already exists in the store, the row is counted in `skippedExisting` and not inserted again.

Email

Customer email. Stored when available.

Financial Status

Payment state. `paid` marks prepaid; `pending`/`unpaid` are treated as unpaid unless payment method says COD.

Paid at

Payment timestamp. Compatibility field; usually optional.

Fulfillment Status

Compatibility field. Our system controls import status.

Fulfilled at

Compatibility fulfillment timestamp.

Accepts Marketing

Compatibility customer marketing flag.

Currency

Currency code, for example `EUR` or `BGN`.

Subtotal

Product subtotal without shipping. Used as fallback with `Shipping` and `Taxes` when `Total` is missing.

Shipping

Shipping amount charged to the customer.

Taxes

Tax amount. Used only for fallback total calculation.

Totalrequired

Final order total and COD base for COD orders. Include shipping, COD fee, and extras when those apply.

COD Fee

Customer COD fee (not courier premium). Shown separately in the order breakdown. Alias: `cod_fee`.

Additional Names

Comma-separated extra services, for example `1xosiguranje-paketa, 1xgarancija`. Imported as upsell lines. Alias: `additional_names`.

Additional Prices

Extra-service prices: one combined sum, or comma-separated values matching the names. Alias: `additional_prices`.

Discount Code

Discount code stored with the order.

Discount Amount

Discount amount stored with the order.

Shipping Methodrequired

Delivery method text, for example `Speedy to_address` or `Econt to_office`.

Created at

Order creation date/time in ISO 8601 format.

Lineitem quantity

Quantity for this line item.

Lineitem namerequired

Product name used in item display and shipment notes.

Lineitem price

Product unit price.

Lineitem compare at price

Fallback item price when `Lineitem price` is missing.

Lineitem sku

Product SKU.

Lineitem requires shipping

Compatibility line item flag.

Lineitem taxable

Compatibility line item tax flag.

Lineitem fulfillment status

Compatibility line item fulfillment state.

Billing Name

Fallback customer name if `Shipping Name` is missing.

Billing Street

Fallback address if shipping address is missing.

Billing Address1

Fallback address line.

Billing Address2

Compatibility billing address line 2.

Billing Company

Compatibility billing company.

Billing City

Fallback city if `Shipping City` is missing.

Billing Zip

Fallback postal code if `Shipping Zip` is missing.

Billing Province

Compatibility billing region.

Billing Country

Stored on the order for multi-country routing (fallback: `Shipping Country`).

Billing Phone

Fallback phone if `Shipping Phone` is missing.

Shipping Namerequired

Customer full name for delivery and waybill creation.

Shipping Street

Fallback/alternative shipping address text.

Shipping Address1required

Main delivery address text.

Shipping Address2

Extra shipping address details.

Shipping Company

Compatibility shipping company.

Shipping Cityrequired

Delivery city used for courier city validation.

Shipping Zip

Postal code. Strongly recommended for courier city matching.

Shipping Province

Compatibility shipping region.

Shipping Country

Fallback country when `Billing Country` is empty.

Shipping Phonerequired

Delivery phone used for search, history, and waybills.

Notes

Customer note and optional pickup-office metadata from some integrations.

Note Attributes

Extra metadata or item properties, used in shipment notes where possible.

Cancelled at

Compatibility cancellation timestamp.

Payment Methodrequired

Use `Cash on Delivery (COD)` for COD orders; otherwise send the prepaid provider/name.

Payment Reference

Compatibility external payment reference.

Refunded Amount

Compatibility refunded amount.

Vendor

Compatibility vendor field.

Outstanding Balance

Compatibility outstanding balance.

Employee

Compatibility POS employee field.

Location

Compatibility Shopify location/POS field.

Device ID

Compatibility POS device field.

Id

External/Shopify id. `Name` is still used as display order code.

Tags

Scanned for risk/report markers and customer verification display.

Risk Level

Compatibility Shopify risk level.

Source

Source channel, useful for debugging.

Lineitem discount

Compatibility per-line discount.

Phone

Fallback phone field.

Courierrequired

API-specific courier column. Allowed values: `Speedy`, `Econt`.

Example

Примерна заявка (директен импорт)

curl — /orders/import
curl -s -X POST   -H "Authorization: Bearer agl_live_KEY"   -H "Content-Type: application/json"   -d '{
    "orders": [
      {
        "Name": "#25001",
        "Created at": "2026-05-18T09:36:39.285Z",
        "Shipping Name": "Ivan Petrov",
        "Email": "ivan@example.com",
        "Shipping Phone": "0888123456",
        "Subtotal": 13.90,
        "Shipping": 3.50,
        "Total": 20.00,
        "COD Fee": 1.60,
        "Additional Names": "1xosiguranje-paketa",
        "Additional Prices": 1,
        "Lineitem quantity": 2,
        "Lineitem name": "Product A",
        "Lineitem price": 6.95,
        "Shipping Method": "Speedy to_address",
        "Shipping Address1": "bul. Bulgaria 1",
        "Shipping City": "Sofia",
        "Shipping Zip": "1000",
        "Billing Country": "BG",
        "Courier": "Speedy",
        "Financial Status": "pending",
        "Payment Method": "Cash on Delivery (COD)",
        "Note Attributes": ""
      }
    ]
  }'   https://www.agility.bg/api/v1/orders/import

Пример — анулация

curl — /orders/cancel
curl -s -X POST \
  -H "Authorization: Bearer agl_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"code":"1024","comment":"Customer requested cancellation"}' \
  https://www.agility.bg/api/v1/orders/cancel

Пример — куриерски статус

curl — /orders/courier-status
curl -s -X GET \
  -H "Authorization: Bearer agl_live_YOUR_KEY" \
  "https://www.agility.bg/api/v1/orders/courier-status?code=1024"

Responses

Отговори

200 — /orders/import

Дубликати: ако `Name` (код на поръчката) вече съществува в същия магазин, редът не се създава отново. Броят им е в `skippedExisting`. Поръчката не се презаписва изцяло; при повторно изпращане могат да се обновят само някои полета (напр. отстъпка/плащане). Еднакви кодове в една заявка се дедуплицират преди запис.

json
{
  "ok": true,
  "useAddressResolver": true,
  "imported": 1,
  "skippedExisting": 0,
  "totalReadyForImport": 1,
  "totalInFile": 1,
  "skipped": 0,
  "parseErrors": [],
  "results": [
    { "name": "1024", "status": "imported", "id": 50122 }
  ]
}
ok

Винаги `true` при успешен HTTP 200.

useAddressResolver

Дали AgilityAI address resolver е бил активен за тази заявка (по подразбиране `true`; изключва се с `useAddressResolver: false` в body).

imported

Колко нови поръчки са записани в Agility при тази заявка.

skippedExisting

Колко валидни реда са пропуснати, защото кодът (`Name`) вече съществува в магазина.

totalReadyForImport

Колко реда са минали валидацията и са готови за запис (преди филтъра за дубликати).

totalInFile

Общ брой подадени поръчки в заявката (вкл. невалидни).

skipped

Брой редове с parse грешки (невалидни данни); вижте `parseErrors`.

parseErrors

Списък `{ line, reason, name? }` за редове, които не са приети заради валидация (`name` е нормализираният код, когато е известен).

results

`results[]` — резултат за всяка подадена поръчка по нормализиран `Name`: `imported` (+ `id`), `skipped_existing`, `skipped_duplicate_in_request`, или `error` (+ `reason`, опционално `line`).

Отговорът може да включва и статистика от pipeline-а (`officeMatched`, `cityErrors`, `statusBreakdown`, `nekorekten`, `timings`, `insertedIds` и др.) — за диагностика, не са задължителни за интеграцията.

4xx / 5xx

`401` невалиден ключ · `403` липсва scope · `409` импорт вече тече · `429` rate limit (Retry-After) · `400`/`422` невалидни данни или над лимитите (500 поръчки / дълги полета).

Security

Сигурност

  • Използвайте само HTTPS в production.
  • Всеки ключ е ограничен до един магазин.
  • Използвайте scopes за least privilege, когато интеграцията не трябва пълен достъп.
  • Rate limits: ~60 req/min на IP; ~30/min на ключ за import/database/cancel; ~120/min за леки GET (вкл. courier-status). При превишаване → `429`.
  • Паралелен sync от базата данни за същия магазин се блокира с `409` (Retry-After).
  • При съмнение отменете ключа и създайте нов.