Activity, Export, and Sync

Audit who did what on an order, export bulk data to CSV for reporting, and force a sync against connected channels.

Base URL

https://api.fenicia.io

All endpoints require Authorization: Bearer fkapi_....


Order activity history

Returns the chronological trace of the order: creation events, state transitions, shipments, cancellations, refunds, etc. Requires orders:read.

orderIdstringrequired

Order ID (path).

limitnumber

Maximum number of entries per page. Default: 50.

offsetnumber

Number of entries to skip from the start. Default: 0.

200
{
  "data": {
    "entries": [
      {
        "id": "act_65f3a1b2c4d5e6f7a8b9c0f1",
        "eventType": "status_changed",
        "source": "api",
        "timestamp": "2026-04-10T14:30:00.000Z",
        "userId": "usr_123",
        "userName": "María López",
        "userEmail": "maria@merchant.example.com",
        "userRole": "admin",
        "details": { "fromStatus": "accepted", "toStatus": "preparing" }
      },
      {
        "id": "act_65f3a1b2c4d5e6f7a8b9c0f0",
        "eventType": "order_accepted",
        "source": "system",
        "timestamp": "2026-04-10T13:10:00.000Z"
      }
    ],
    "totalCount": 14,
    "hasMore": true,
    "pagination": { "limit": 50, "offset": 0, "nextOffset": 50 }
  }
}

Real shape of an entry

Each entry is { id?, timestamp, eventType, source, details?, userId?, userName?, userEmail?, userRole?, quotaImpact? }. The event field is eventType, not action; transition data (for example fromStatus/toStatus) goes inside details when applicable, not as top-level fields.

curl "https://api.fenicia.io/orders/65f3a1b2c4d5e6f7a8b9c0d1/activity-log?limit=100&offset=0" \
  -H "Authorization: Bearer fkapi_your_api_key"

Tip

To paginate forward, use pagination.nextOffset as the next offset. When hasMore is false, there are no more entries.


Export orders to CSV

Exports the orders matching the filters to a CSV file. Requires orders:export.

columnsstringrequired

Comma-separated list of column paths to include. Supports nested paths, e.g. customerInfo.email.

localestring

Locale used to format values in the CSV. Default: es.

maxRecordsnumber

Maximum number of records to export. Default: 10000.

startDatestring

ISO start date of the range (inclusive).

endDatestring

ISO end date of the range (inclusive).

orderStatusstring

Filter by order status. Also accepts the status alias.

channelIdsstring

Filter by one or more channels.

metafieldsstring

Additional filter by metafields, in JSON format.

200The rest of the listing filters (see List Orders) also apply to this endpoint.
Content-Type: text/csv
Content-Disposition: attachment; filename="pedidos-2026-04-11.csv"
 
externalId,customerInfo.email,total,orderStatus
1001,ana@example.com,1500.00,accepted
1002,luis@example.com,780.50,fulfilled

There is no format parameter

This endpoint always returns raw CSV (Content-Type: text/csv), never JSON. There is no format parameter to choose another output — if you send one, it's ignored. columns is required: without it, the API responds with a validation error.

The date range uses startDate / endDate, not from / to

This endpoint reuses the same filter normalizer as GET /orders (see List Orders). The date range is filtered with startDate and endDate — the names from/to don't exist in this API.

curl "https://api.fenicia.io/orders/export?columns=externalId,customerInfo.email,total,orderStatus&startDate=2026-04-01&endDate=2026-04-30" \
  -H "Authorization: Bearer fkapi_your_api_key" \
  -o pedidos.csv

List orders with overdue settlement

Paginated list of orders whose channel settlement is overdue beyond the configured grace period. Requires orders:read.

pagenumber

Page number.

limitnumber

Items per page.

gracePeriodDaysnumber

Grace period in days before a settlement is considered overdue.

channelIdstring

Filter by channel.

startDatestring

ISO start date of the range (inclusive).

endDatestring

ISO end date of the range (inclusive).

200
{
  "data": [
    {
      "_id": "65f3a1b2c4d5e6f7a8b9c0d1",
      "externalId": "FEN-10042",
      "channelId": "chn_shopify_01",
      "orderStatus": "delivered",
      "total": 1986.26
    }
  ],
  "meta": {
    "pagination": { "page": 0, "limit": 20, "total": 6, "totalPages": 1, "hasMore": false }
  }
}

Previously undocumented endpoint

This endpoint exists and works in the public API, but had no documentation until this page. Unlike the abandoned carts listing, it follows the domain's standard envelope: { data: [...], meta: { pagination } }.


Export orders with overdue settlement

Exports to CSV the orders with overdue settlement, with the same filters as the listing. Requires orders:export.

gracePeriodDaysnumber

Grace period in days before a settlement is considered overdue.

channelIdstring

Filter by channel.

startDatestring

ISO start date of the range (inclusive).

endDatestring

ISO end date of the range (inclusive).

200Analogous to GET /orders/export.
Content-Type: text/csv
Content-Disposition: attachment; filename="liquidacion-vencida-2026-04-11.csv"

Previously undocumented endpoint

Same as GET /orders/settlement-overdue, this endpoint exists and works but had no documentation until this page.


Sync all orders

Queues an asynchronous sync of orders from all connected, active channels. Requires orders:manage.

{}
202
{
  "data": {
    "message": "Sync initiated",
    "status": "processing",
    "channelCount": 4
  }
}

No body required; the message travels in English

This endpoint doesn't read any field from the body — send {} or no body at all, it makes no difference. The real response carries channelCount (number of channels queued), not channelsQueued, and the message field is literally "Sync initiated" (in English, exactly as the handler returns it) — don't translate it when showing it to your end user without first confirming it's a data value, not an i18n key. It also always includes status: "processing".

curl -X POST https://api.fenicia.io/orders/sync \
  -H "Authorization: Bearer fkapi_your_api_key"

Sync a single order

Forces the sync of a specific order against its source channel. Requires orders:manage.

orderIdstringrequired

Order ID.

{}
202
{
  "data": {
    "message": "Order sync initiated",
    "status": "processing",
    "orderId": "65f3a1b2c4d5e6f7a8b9c0d1"
  }
}
404
{ "error": { "code": "sync:channel_not_found", "message": "Cannot sync order 65f3a1b2c4d5e6f7a8b9c0d1" } }
curl -X POST https://api.fenicia.io/orders/65f3a1b2c4d5e6f7a8b9c0d1/sync \
  -H "Authorization: Bearer fkapi_your_api_key"

Tip

Both sync endpoints are asynchronous. Subscribe to the order.updated webhook or poll GET /orders/{orderId} again to detect when it finishes.


Errors

CodeStatusDescription
orders:not_found404No order with that ID exists in your tenant.
sync:channel_not_found404The channel to sync doesn't exist or doesn't belong to the tenant.
sync:channel_disabled409The channel exists but is disabled.
sync:integration_error502The channel's integration returned an error while syncing.
sync:rate_limited429The allowed sync limit was reached in the current window.
validation:invalid_pagination400page, limit, or offset has a value out of range.
validation:invalid_date_range400startDate is later than endDate.
auth:invalid_token401The API key is invalid or was revoked.
auth:permission_denied403The API key doesn't have the required permission (orders:read, orders:export, or orders:manage, depending on the endpoint).

Next steps