REKKI orders API
The orders API from REKKI — 11 operation(s) for orders.
The orders API from REKKI — 11 operation(s) for orders.
swagger: '2.0'
info:
description: 'The base URL for all API endpoints is https://api.rekki.com/api
Api key value consists of word Bearer together with api key that you can get from integrations@rekki.com
'
title: Rekki.com Supplier catalog orders API
contact:
email: integrations@rekki.com
license:
name: All rights reserved
version: ''
host: api.rekki.com
basePath: /api
schemes:
- https
tags:
- name: orders
paths:
/integration/v1/orders/confirm:
post:
security:
- ApiKeyAuth: []
description: 'Notifies the buyer that the order has been acknowledged.
Status:` 200 OK`
Body: `{ success: true}`
Status: `400 Conflict`
Body: `{"error":"Order already confirmed","order_id":...}`
Status: `400 Not Found`
Body: `{"error":"Order not found","order_id":...}`
in errors order_id denotes the order that failed to be confirmed
**the processing stops at first error**
'
consumes:
- application/json
produces:
- application/json
tags:
- orders
summary: Confirm a pending order by its reference code.
operationId: ConfirmOrders
deprecated: true
parameters:
- enum:
- supplier_api_token
type: string
description: Required header
name: X-REKKI-Authorization-Type
in: header
required: true
- description: Payload
name: input
in: body
required: true
schema:
$ref: '#/definitions/main.SetIntegrateOrdersInput'
responses:
'200':
description: OK
schema:
$ref: '#/definitions/main.SetIntegrateOrdersInput'
'400':
description: Bad Request
schema:
$ref: '#/definitions/main.FailedOrderError'
'401':
description: Unauthorized
schema:
type: string
'500':
description: Internal Server Error
schema:
type: string
/integration/v1/orders/list:
post:
security:
- ApiKeyAuth: []
description: "Orders are limited to max 30 days old (i.e. timestamp must be within 30 days).\n\nWe recommend polling for orders by setting the new request timestamp to the time of the last successful request.\n\nAfter you start using the API, you should request orders since last received order's inserted_at_ts, since the API returns orders created >= of the requested timestamp, you will always get at order from which you took the timestamp in the response. This will be explained again in the provided example.\n\nKeep in mind that since you can have more than one order per since, you must not do since: last_order.inserted_at_ts + 1, but keep the last order you received's reference and ignore the duplicate.\n\nAfter you start using the API, you should request orders since last received order's inserted_at_ts, since the API returns orders created >= of the requested timestamp, you will **always** get at order from which you took the timestamp in the response. This will be explained again in the provided example.\n\nKeep in mind that since you can have more than one order per since, you must not do since: last_order.inserted_at_ts + 1, but keep the last order you received's reference and ignore the duplicate.\n\n## Exaple usage\n\nIn this JavaScript example, all orders are retrieved. Then it keeps pulling for new orders since the last order, every hour.\n\n ```\n const fetch = require(\"node-fetch\");\n\n const sleep = function sleep(ms) {\n return new Promise(resolve => setTimeout(resolve, ms));\n };\n\n const fetch_orders = async function(token, since) {\n let r = await fetch(\n \"https://api.rekki.com/api/catalog/integration/list_orders_by_supplier\",\n {\n method: \"POST\",\n headers: {\n Authorization: \"Bearer \" + token,\n \"X-REKKI-Authorization-Type\": \"supplier_api_token\",\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\"\n },\n body: JSON.stringify({ since })\n }\n );\n return await r.json();\n };\n\n const poll = async function(token, last_rekki_order_time) {\n let last_order_reference = undefined;\n\n while (true) {\n console.log(\"requesting orders since \" + last_rekki_order_time);\n let response = await fetch_orders(token, last_rekki_order_time);\n\n for (let order of response.orders) {\n if (order.reference == last_order_reference) {\n // here is where we are ignoring the order we\n // took the inserted_at_ts from\n // but since we can have more orders in the same inserted_at_ts\n // you can't just do since: inserted_at_ts+1\n continue;\n }\n if (order.inserted_at_ts >= last_rekki_order_time) {\n last_rekki_order_time = order.inserted_at_ts;\n last_order_reference = order.reference;\n }\n\n // process(order)\n console.log(order);\n }\n await sleep(3600 * 1000); // wait 1 hour\n }\n };\n\n poll(\"XXXXXXX-XXXX-XXXX-XXXXX-XXXXXXXXXXXX\", parseInt((+new Date() /1000) - 3600 * 24 * 30));\n ```\n"
consumes:
- application/json
produces:
- application/json
tags:
- orders
summary: Lists all orders placed for the supplier that were placed through REKKI.
operationId: ListOrdersBySupplier
deprecated: true
parameters:
- enum:
- supplier_api_token
type: string
description: Required header
name: X-REKKI-Authorization-Type
in: header
required: true
- description: Payload
name: input
in: body
required: true
schema:
$ref: '#/definitions/main.OrderListInput'
responses:
'200':
description: OK
schema:
$ref: '#/definitions/main.OrderListOutput'
'400':
description: Bad Request
schema:
$ref: '#/definitions/main.GenericErrorResponse'
'401':
description: Unauthorized
schema:
type: string
'500':
description: Internal Server Error
schema:
type: string
/integration/v1/orders/list_not_integrated:
post:
security:
- ApiKeyAuth: []
consumes:
- application/json
produces:
- application/json
tags:
- orders
summary: Lists all orders placed for the supplier that were placed through REKKI and not marked as integrated.
operationId: ListNotIntegratedOrders
deprecated: true
parameters:
- enum:
- supplier_api_token
type: string
description: Required header
name: X-REKKI-Authorization-Type
in: header
required: true
- description: Payload
name: input
in: body
required: true
schema:
$ref: '#/definitions/main.OrderListInput'
responses:
'200':
description: OK
schema:
$ref: '#/definitions/main.OrderListOutput'
'400':
description: Bad Request
schema:
$ref: '#/definitions/main.GenericErrorResponse'
'401':
description: Unauthorized
schema:
type: string
'500':
description: Internal Server Error
schema:
type: string
/integration/v1/orders/set_error:
post:
security:
- ApiKeyAuth: []
consumes:
- application/json
produces:
- application/json
tags:
- orders
summary: Report failure to integrate an order
operationId: MarkIntegrationError
deprecated: true
parameters:
- enum:
- supplier_api_token
type: string
description: Required header
name: X-REKKI-Authorization-Type
in: header
required: true
- description: Payload
name: input
in: body
required: true
schema:
$ref: '#/definitions/main.SetErrorOrderInput'
responses:
'200':
description: OK
schema:
$ref: '#/definitions/main.SuccessConfirmation'
'400':
description: Bad Request
schema:
$ref: '#/definitions/main.FailedOrderError'
'401':
description: Unauthorized
schema:
type: string
'500':
description: Internal Server Error
schema:
type: string
/integration/v1/orders/set_integrated:
post:
security:
- ApiKeyAuth: []
consumes:
- application/json
produces:
- application/json
tags:
- orders
summary: Mark orders as integrated
operationId: MarkOrdersIntegrated
deprecated: true
parameters:
- enum:
- supplier_api_token
type: string
description: Required header
name: X-REKKI-Authorization-Type
in: header
required: true
- description: Payload
name: input
in: body
required: true
schema:
$ref: '#/definitions/main.SetIntegrateOrdersInput'
responses:
'200':
description: OK
schema:
$ref: '#/definitions/main.UpdateSuccess'
'400':
description: Bad Request
schema:
$ref: '#/definitions/main.GenericErrorResponse'
'401':
description: Unauthorized
schema:
type: string
'500':
description: Internal Server Error
schema:
type: string
/integration/v3/orders/confirm:
post:
security:
- ApiKeyAuth: []
description: 'Notifies the buyer that the order has been acknowledged.
Status:` 200 OK`
Body: `{ success: true}`
Status: `400 Conflict`
Body: `{"error":"Order already confirmed","order_id":...}`
Status: `400 Not Found`
Body: `{"error":"Order not found","order_id":...}`
in errors order_id denotes the order that failed to be confirmed
**the processing stops at first error**
'
consumes:
- application/json
produces:
- application/json
tags:
- orders
summary: Confirm a pending order by its reference code.
operationId: ConfirmOrdersV3
parameters:
- enum:
- supplier_api_token
type: string
description: Required header
name: X-REKKI-Authorization-Type
in: header
required: true
- description: Payload
name: input
in: body
required: true
schema:
$ref: '#/definitions/v3.ConfirmOrdersInput'
responses:
'200':
description: OK
schema:
$ref: '#/definitions/v3.ConfirmOrdersInput'
'400':
description: Bad Request
schema:
$ref: '#/definitions/v3.FailedOrderError'
'401':
description: Unauthorized
schema:
type: string
'500':
description: Internal Server Error
schema:
type: string
/integration/v3/orders/list:
post:
security:
- ApiKeyAuth: []
description: "**UPDATE TO REFLECT V3 CHANGES**\n\nOrders are limited to max 30 days old (i.e. timestamp must be within 30 days).\n\nWe recommend polling for orders by setting the new request timestamp to the time of the last successful request.\n\nAfter you start using the API, you should request orders since last received order's inserted_at_ts, since the API returns orders created >= of the requested timestamp, you will always get at order from which you took the timestamp in the response. This will be explained again in the provided example.\n\nKeep in mind that since you can have more than one order per since, you must not do since: last_order.inserted_at_ts + 1, but keep the last order you received's reference and ignore the duplicate.\n\nAfter you start using the API, you should request orders since last received order's inserted_at_ts, since the API returns orders created >= of the requested timestamp, you will **always** get at order from which you took the timestamp in the response. This will be explained again in the provided example.\n\nKeep in mind that since you can have more than one order per since, you must not do since: last_order.inserted_at_ts + 1, but keep the last order you received's reference and ignore the duplicate.\n\n## Example usage\n\nIn this JavaScript example, all orders are retrieved. Then it keeps pulling for new orders since the last order, every hour.\n\n ```\n const fetch = require(\"node-fetch\");\n\n const sleep = function sleep(ms) {\n return new Promise(resolve => setTimeout(resolve, ms));\n };\n\n const fetch_orders = async function(token, since) {\n let r = await fetch(\n \"https://api.rekki.com/api/catalog/integration/list_orders_by_supplier\",\n {\n method: \"POST\",\n headers: {\n Authorization: \"Bearer \" + token,\n \"X-REKKI-Authorization-Type\": \"supplier_api_token\",\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\"\n },\n body: JSON.stringify({ since })\n }\n );\n return await r.json();\n };\n\n const poll = async function(token, last_rekki_order_time) {\n let last_order_reference = undefined;\n\n while (true) {\n console.log(\"requesting orders since \" + last_rekki_order_time);\n let response = await fetch_orders(token, last_rekki_order_time.toISOString());\n\n for (let order of response.orders) {\n if (order.reference == last_order_reference) {\n // here is where we are ignoring the order we\n // took the inserted_at from\n // but since we can have more orders in the same inserted_at\n // you can't just do since: inserted_at + 1 second\n continue;\n }\n if (+new Date(order.inserted_at) >= +last_rekki_order_time) {\n last_rekki_order_time = order.inserted_at;\n last_order_reference = order.reference;\n }\n\n // process(order)\n console.log(order);\n }\n await sleep(3600 * 1000); // wait 1 hour\n }\n };\n\n let startDate = new Date()\n startDate.setDate(startDate.getDate() - 30)\n poll(\"XXXXXXX-XXXX-XXXX-XXXXX-XXXXXXXXXXXX\", startDate)\n ```\n"
consumes:
- application/json
produces:
- application/json
tags:
- orders
summary: Lists all orders placed for the supplier that were placed through REKKI.
operationId: ListOrdersBySupplierV3
parameters:
- enum:
- supplier_api_token
type: string
description: Required header
name: X-REKKI-Authorization-Type
in: header
required: true
- description: Payload
name: input
in: body
required: true
schema:
$ref: '#/definitions/v3.OrderListInput'
responses:
'200':
description: OK
schema:
$ref: '#/definitions/v3.OrderListOutput'
'400':
description: Bad Request
schema:
$ref: '#/definitions/v3.GenericErrorResponse'
'401':
description: Unauthorized
schema:
type: string
'500':
description: Internal Server Error
schema:
type: string
/integration/v3/orders/set_error:
post:
security:
- ApiKeyAuth: []
consumes:
- application/json
produces:
- application/json
tags:
- orders
summary: Report failure to integrate an order
operationId: MarkIntegrationErrorV3
parameters:
- enum:
- supplier_api_token
type: string
description: Required header
name: X-REKKI-Authorization-Type
in: header
required: true
- description: Payload
name: input
in: body
required: true
schema:
$ref: '#/definitions/v3.SetErrorOrderInput'
responses:
'200':
description: OK
schema:
$ref: '#/definitions/v3.SuccessConfirmation'
'400':
description: Bad Request
schema:
$ref: '#/definitions/v3.FailedOrderError'
'401':
description: Unauthorized
schema:
type: string
'500':
description: Internal Server Error
schema:
type: string
/integration/v3/orders/set_integrated:
post:
security:
- ApiKeyAuth: []
consumes:
- application/json
produces:
- application/json
tags:
- orders
summary: Mark orders as integrated
operationId: MarkOrdersIntegratedV3
parameters:
- enum:
- supplier_api_token
type: string
description: Required header
name: X-REKKI-Authorization-Type
in: header
required: true
- description: Payload
name: input
in: body
required: true
schema:
$ref: '#/definitions/v3.SetIntegratedOrdersInput'
responses:
'200':
description: OK
schema:
$ref: '#/definitions/v3.UpdateSuccess'
'400':
description: Bad Request
schema:
$ref: '#/definitions/v3.GenericErrorResponse'
'401':
description: Unauthorized
schema:
type: string
'500':
description: Internal Server Error
schema:
type: string
/integration/v4/orders/set_integrated:
post:
description: "This endpoint allows you to mark orders as integrated (success) in REKKI's records.\n\n\n **Payload:**\n\n\n - For each order, you are required to provide a `Reference ID` and an `External ID`.\n\n - The `Reference ID` is the REKKI order reference, i.e. **U8806513**.\n\n - The `External ID` is the Order ID in your system, i.e. **SO-25001**.\n\n - If you can not provide an `External ID`, you can pass the same value used for the `Reference ID`.\n\n\n\n **200 Response:**\n\n\n - Response will contain separate lists for `updated`, `failed`, and `skipped`.\n\n - Each order will also have a list of `messages` with details about the attempt.\n "
security:
- ApiKeyAuth: []
consumes:
- application/json
produces:
- application/json
tags:
- orders
summary: Mark orders as integrated
operationId: MarkOrdersIntegratedV4
parameters:
- enum:
- supplier_api_token
type: string
description: Required header
name: X-REKKI-Authorization-Type
in: header
required: true
- description: Payload
name: input
in: body
required: true
schema:
$ref: '#/definitions/v4.SetIntegratedOrdersInput'
responses:
'200':
description: OK
schema:
$ref: '#/definitions/v4.IntegratedOrdersResponse'
'400':
description: Bad Request
schema:
$ref: '#/definitions/v3.GenericErrorResponse'
'401':
description: Unauthorized
schema:
type: string
'500':
description: Internal Server Error
schema:
type: string
/integration/v4/orders/list:
post:
security:
- ApiKeyAuth: []
description: "**IMPORTANT - v4 onwards**\n\nCallers **must** use an appropriate JSON parser to parse the output. **Do not** use any sort of simple pattern matching or regular expression-based solution.\n\nThe order of fields in the JSON output is not guaranteed and REKKI may add new fields any time.\n\n**UPDATE TO REFLECT V4 CHANGES**\n\n### The output payload structure has changed:\n\n- Fields `inserted_at, inserted_at_ts, confirmed_by` were added\n - `confirmed_by` can be null\n- Field `external_po_number` will always be present in the output, but can be null\n- `size` field was added to the order items. It was previously obtainable via an optional input parameter.\n- An `integration` field has been added, containing two nested fields:\n - `status`, which can be `pending`, `failed` or `success`\n - `integrated_at`, which will show the timestamp of a successful integration or be null otherwise.\n\nIn general, all fields will always be present, though certain fields can have null values. Check each field specification for details.\n\n### The input payload structure has changed:\n\n- Removed the `skip_integrated`, `show_previous_attempts` and `extra_item_fields` fields.\n- Added a `filter` field.\n - currently has a nested `integration_statuses` field, which can be used to specify the statuses of the orders to be listed.\n - by default, no filter is applied.\n\nOrders are limited to 1 month old at a maximum, i.e. if `since` contains an older timestamp, it will be disregarded and a limit of 1 month will be used.\n\n**RELEVANT INFORMATION FROM PREVIOUS VERSIONS**\n\nWe recommend polling for orders by setting the new request timestamp to the time of the last successful request.\n\nAfter you start using the API, you should request orders since last received order's inserted_at_ts, since the API returns orders created >= of the requested timestamp, you will always get at order from which you took the timestamp in the response. This will be explained again in the provided example.\n\nKeep in mind that since you can have more than one order per since, you must not do since: last_order.inserted_at_ts + 1, but keep the last order you received's reference and ignore the duplicate.\n\nAfter you start using the API, you should request orders since last received order's inserted_at_ts, since the API returns orders created >= of the requested timestamp, you will **always** get at order from which you took the timestamp in the response. This will be explained again in the provided example.\n\nKeep in mind that since you can have more than one order per since, you must not do since: last_order.inserted_at_ts + 1, but keep the last order you received's reference and ignore the duplicate.\n\n## Example usage\n\nIn this JavaScript example, all orders are retrieved. Then it keeps pulling for new orders since the last order, every hour.\n\n ```\n const fetch = require(\"node-fetch\");\n\n const sleep = function sleep(ms) {\n return new Promise(resolve => setTimeout(resolve, ms));\n };\n\n const fetch_orders = async function(token, since) {\n let r = await fetch(\n \"https://api.rekki.com/api/integration/v4/orders/list\",\n {\n method: \"POST\",\n headers: {\n Authorization: \"Bearer \" + token,\n \"X-REKKI-Authorization-Type\": \"supplier_api_token\",\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\"\n },\n body: JSON.stringify({ since })\n }\n );\n return await r.json();\n };\n\n const poll = async function(token, last_rekki_order_time) {\n let last_order_reference = undefined;\n\n while (true) {\n console.log(\"requesting orders since \" + last_rekki_order_time);\n let response = await fetch_orders(token, last_rekki_order_time.toISOString());\n\n for (let order of response.orders) {\n if (order.reference == last_order_reference) {\n // here is where we are ignoring the order we\n // took the inserted_at from\n // but since we can have more orders in the same inserted_at\n // you can't just do since: inserted_at + 1 second\n continue;\n }\n if (+new Date(order.inserted_at) >= +last_rekki_order_time) {\n last_rekki_order_time = order.inserted_at;\n last_order_reference = order.reference;\n }\n\n // process(order)\n console.log(order);\n }\n await sleep(3600 * 1000); // wait 1 hour\n }\n };\n\n let startDate = new Date()\n startDate.setDate(startDate.getDate() - 30)\n poll(\"XXXXXXX-XXXX-XXXX-XXXXX-XXXXXXXXXXXX\", startDate)\n ```\n"
consumes:
- application/json
produces:
- application/json
tags:
- orders
summary: Lists all orders placed for the supplier that were placed through REKKI.
operationId: ListOrdersBySupplierV4
parameters:
- enum:
- supplier_api_token
type: string
description: Required header
name: X-REKKI-Authorization-Type
in: header
required: true
- description: Payload
name: input
in: body
required: true
schema:
$ref: '#/definitions/v4.OrderListInput'
responses:
'200':
description: OK
schema:
$ref: '#/definitions/v4.OrderListOutput'
'400':
description: Bad Request
schema:
$ref: '#/definitions/v4.GenericErrorResponse'
'401':
description: Unauthorized
schema:
type: string
'500':
description: Internal Server Error
schema:
type: string
definitions:
v3.ConfirmOrdersInput:
type: object
properties:
orders:
description: Array of References of the orders to confirm, required. Order refs are discoverable when listing orders.
type: array
items:
type: string
main.GenericErrorResponse:
type: object
properties:
error:
type: string
v3.OrderIntegrationError:
type: object
properties:
attempts:
description: Number of attempts made to push the integration
type: integer
error:
description: error message
type: string
product_code:
description: product code
type: string
reference:
description: Order reference
type: string
main.UpdateSuccess:
type: object
properties:
affected:
description: number of items actually updated
type: integer
success:
type: boolean
example: true
v4.OrderResponseInfo:
type: object
properties:
reference_id:
type: string
description: REKKI's order reference
external_id:
type: string
description: External order reference, if applicable
messages:
type: array
items:
type: string
v3.SetErrorOrderInput:
type: object
properties:
orders:
description: list of orders failed to integrate, required
type: array
items:
$ref: '#/definitions/v3.OrderIntegrationError'
v3.Order:
type: object
properties:
confirmed_at:
description: the time at which the supplier confirmed the order (via email, or via the REKKI supplier app, or via the REKKI API)
type: string
example: '2019-08-12T12:20:10-07:00'
contact_email:
description: the email for the person who placed the order
type: string
contact_info:
description: the phone number or email address for the person who placed the order
type: string
contact_name:
description: the full name of the person who placed the order
type: string
customer_account_no:
description: the account number for customer within the supplier system, this can be setup in REKKI supplier app ( https://supplier.rekki.com ).
type: string
delivery_address:
description: delivery address for this specific order
$ref: '#/definitions/v3.DeliveryAddress'
delivery_instructions:
description: defined by the user at the moment of making an order (e.g. "opening hours 8am - 4pm.")
type: string
delivery_on:
description: expected delivery date (when users place orders they specify for which day it is supposed to be delivered)
type: string
example: '2020-06-01'
external_po_number:
description: External Purchase Order Number for orders placed via external systems (e.g. "PO123")
type: string
inserted_at:
description: when was the order created by the customer (ISO date time)
type: string
inserted_at_ts:
description: when was the order created by the customer (unix timestamp in seconds)
type: integer
items:
description: items requests in this order
type: array
items:
$ref: '#/definitions/v3.OrderItem'
location_name:
description: the name of the location that placed the order, can be NULL
type: string
notes:
description: defined by the user at the moment of making an order and usually refer to that specific order (e.g. "please send fresher tomatoes")
type: string
reference:
description: REKKI's order reference
type: string
supplier_notes:
description: 'notes define by the user for the supplier, usually being common across orders (e.g.: "please use the side entrance for delivery")'
type: string
tags:
description: tags for this order
type: array
items:
type: string
integration.Order:
type: object
properties:
confirmed_at:
description: the time at which the supplier confirmed the order (via email, or via the REKKI supplier app, or via the REKKI API)
type: string
example: '2019-08-12T12:20:10-07:00'
contact_email:
description: the email for the person who placed the order
type: string
contact_info:
description: the phone number or email address for the person who placed the order
type: string
contact_name:
description: the full name of the person who placed the order
type: string
customer_account_no:
description: the account number for customer within the supplier system, this can be setup in REKKI supplier app ( https://supplier.rekki.com ).
type: string
delivery_address:
description: delivery address for this specific order (address, postcode)
type: string
delivery_on:
description: expected delivery date (when users place orders they specify for which day it is supposed to be delivered)
type: string
example: '2020-06-01'
external_po_number:
description: External Purchase Order Number for orders placed via external systems (e.g. "PO123")
type: string
inserted_at:
description: when was the order created by the customer (ISO date time)
type: string
inserted_at_ts:
description: when was the order created by the customer (unix timestamp in seconds)
type: integer
items:
description: items requests in this order
type: array
items:
$ref: '#/definitions/integration.OrderItem'
location_name:
description: the name of the location that placed the order, can be NULL
type: string
notes:
description: defined by the user at the moment of making an order and usually refer to that specific order (e.g. "please send fresher tomatoes")
type: string
reference:
description: REKKI's order reference
type: string
supplier_notes:
description: 'notes define by the user for the supplier, usually being common across orders (e.g.: "please use the side entrance for delivery")'
type: string
main.SuccessConfirmation:
type: object
properties:
success:
type: boolean
example: true
v4.GenericErrorResponse:
type: object
properties:
error:
type: string
v4.IntegrationData:
type: object
properties:
integrated_at:
description: The time when the order was integrated successfully, or null if it was not integrated yet.
type: string
status:
description: 'The integration status. Can be one of: pending, done, failed'
type: string
main.FailedOrderError:
type: object
properties:
error:
type: string
order_id:
type: any
v4.IntegratedOrdersResponse:
type:
# --- truncated at 32 KB (43 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/rekki/refs/heads/main/openapi/rekki-orders-api-openapi.yml