curl "https://api.alura.io/v1/workspace/customers?repeat=true&sort=-lifetime_value" \
-H "Authorization: Bearer $ALURA_API_KEY"const res = await fetch('https://api.alura.io/v1/workspace/customers?repeat=true&sort=-lifetime_value', {
headers: {
Authorization: `Bearer ${process.env.ALURA_API_KEY}`,
},
});
console.log(await res.json());import json
import os
import urllib.request
request = urllib.request.Request(
"https://api.alura.io/v1/workspace/customers?repeat=true&sort=-lifetime_value",
headers={
"Authorization": f"Bearer {os.environ['ALURA_API_KEY']}",
},
)
with urllib.request.urlopen(request) as response:
print(json.load(response)){
"object": "list",
"data": [
{
"object": "workspace.customer",
"id": "4242",
"shop_ids": [
"22841907",
"30577120"
],
"name": "Jane Example",
"image_url": null,
"location": {
"country": "US",
"city": "Portland"
},
"orders": 4,
"items": 5,
"first_order_at": "2025-11-02T15:20:00.000Z",
"last_order_at": "2026-10-05T18:45:00.000Z",
"repeat": true,
"lifetime_value": {
"amount": "138.40",
"currency": "USD",
"usd": "138.40"
},
"average_order_value": {
"amount": "34.60",
"currency": "USD",
"usd": "34.60"
},
"refunds": {
"count": 1,
"amount": {
"amount": "12.00",
"currency": "USD",
"usd": "12.00"
}
},
"reviews": {
"count": 3,
"average": 4.67
},
"as_of": "2026-10-08T06:00:00.000Z"
}
],
"has_more": false,
"next_cursor": null,
"total": {
"value": 1,
"relation": "eq"
},
"summary": {
"as_of": "2026-10-08T06:00:00.000Z",
"freshness": [
{
"shop_id": "22841907",
"as_of": "2026-10-08T06:00:00.000Z"
},
{
"shop_id": "30577120",
"as_of": "2026-10-17T06:00:00.000Z"
},
{
"shop_id": "48911633",
"as_of": "2026-10-16T06:00:00.000Z"
}
],
"notices": [
{
"code": "stale_shops",
"shop_ids": [
"22841907"
],
"detail": "These shops have no data, or no data newer than 7 days, for this area. Start a sync to refresh them."
},
{
"code": "lifetime_value_ranked_by_stored_total",
"shop_ids": [
"22841907",
"30577120",
"48911633"
],
"detail": "Ranked by the lifetime total Alura stored for each customer. A customer whose total Alura cannot verify against the stored orders keeps that rank with lifetime_value null; customers with no stored total come last."
}
],
"fx_as_of": "2026-10-17T00:00:00.000Z"
}
}{
"type": "https://docs.alura.io/errors/invalid_request",
"title": "Invalid request",
"status": 400,
"code": "invalid_request",
"detail": "Invalid request",
"suggestion": "Fix the request as the detail says, then send it again.",
"retryable": false,
"request_id": "req_01JQ5W3H8M2N4P6R8T0V2X4Z6B"
}{
"type": "https://docs.alura.io/errors/unauthorized",
"title": "Unauthorized",
"status": 401,
"code": "unauthorized",
"detail": "Unauthorized",
"suggestion": "Send a valid API key as `Authorization: Bearer alura_sk_...`.",
"retryable": false,
"request_id": "req_01JQ5W3H8M2N4P6R8T0V2X4Z6B"
}{
"type": "https://docs.alura.io/errors/credits_exhausted",
"title": "API credits exhausted",
"status": 402,
"code": "credits_exhausted",
"detail": "API credits exhausted",
"suggestion": "Upgrade the plan or wait for the monthly reset.",
"retryable": false,
"request_id": "req_01JQ5W3H8M2N4P6R8T0V2X4Z6B"
}{
"type": "https://docs.alura.io/errors/plan_required",
"title": "Plan required",
"status": 403,
"code": "plan_required",
"detail": "Plan required",
"suggestion": "Upgrade the workspace plan to use this operation.",
"retryable": false,
"request_id": "req_01JQ5W3H8M2N4P6R8T0V2X4Z6B"
}{
"type": "https://docs.alura.io/errors/not_found",
"title": "Not found",
"status": 404,
"code": "not_found",
"detail": "Not found",
"suggestion": "Check the ID, or search for it first.",
"retryable": false,
"request_id": "req_01JQ5W3H8M2N4P6R8T0V2X4Z6B"
}{
"type": "https://docs.alura.io/errors/method_not_allowed",
"title": "Method not allowed",
"status": 405,
"code": "method_not_allowed",
"detail": "Method not allowed",
"suggestion": "Use one of the methods in the Allow header.",
"retryable": false,
"request_id": "req_01JQ5W3H8M2N4P6R8T0V2X4Z6B"
}{
"type": "https://docs.alura.io/errors/rate_limited",
"title": "Rate limited",
"status": 429,
"code": "rate_limited",
"detail": "Rate limited",
"suggestion": "Wait for Retry-After, then retry.",
"retryable": true,
"request_id": "req_01JQ5W3H8M2N4P6R8T0V2X4Z6B"
}{
"type": "https://docs.alura.io/errors/internal_error",
"title": "Internal error",
"status": 500,
"code": "internal_error",
"detail": "Internal error",
"suggestion": "Retry; if it keeps failing, report the request_id.",
"retryable": true,
"request_id": "req_01JQ5W3H8M2N4P6R8T0V2X4Z6B"
}{
"type": "https://docs.alura.io/errors/credits_unavailable",
"title": "API credits unavailable",
"status": 503,
"code": "credits_unavailable",
"detail": "API credits unavailable",
"suggestion": "Retry shortly.",
"retryable": true,
"request_id": "req_01JQ5W3H8M2N4P6R8T0V2X4Z6B"
}Search customers
Lists the customers (Etsy buyers) of your connected Etsy shops: filter repeat customers (repeat) and by when they ordered (ordered_after, ordered_before); sort by lifetime value, orders, last order or first order, most recent last order first by default. The lifetime value sort ranks by the total Alura stored for each customer (in USD): a customer whose total Alura cannot verify against the stored orders keeps that rank with lifetime_value: null, and a lifetime_value_ranked_by_stored_total notice says so; customers with no stored total come last. A buyer who ordered from several of your connected shops is one customer, summed over the selected shops (counts and amounts summed, the average order value recomputed, the review average weighted, the name and location from the shop ordered from last). Guest checkouts (no Etsy account) are not customers. An amount Alura cannot vouch for (a payment, item or refund it has not stored) is null, never a short total; amounts in several currencies give only usd. A customer’s orders are GET /v1/workspace/orders?buyer_id=. A shop whose customers Alura has not computed yet is left out and named in a customers_not_computed notice. Covers every connected shop unless shop_id narrows it; a shop outside the workspace is 404. summary gives each shop’s data time and a stale_shops notice for shops not synced for 7 days. The results hold buyer names and cities (personal data, as Etsy provides it). To filter by name or country, use POST /v1/workspace/customers/search with them in the JSON body: this GET takes no free text, so buyer data never goes in a URL (URLs are kept in request logs). A large workspace may take up to 10 seconds: every customer of the selected shops is merged before sorting; past that, a retryable 503. Needs the customers:read scope and the Customer analytics workspace permission. Costs 1 API credit per page with results; an empty page is free.
Cost: 1 API credit per page.
curl "https://api.alura.io/v1/workspace/customers?repeat=true&sort=-lifetime_value" \
-H "Authorization: Bearer $ALURA_API_KEY"const res = await fetch('https://api.alura.io/v1/workspace/customers?repeat=true&sort=-lifetime_value', {
headers: {
Authorization: `Bearer ${process.env.ALURA_API_KEY}`,
},
});
console.log(await res.json());import json
import os
import urllib.request
request = urllib.request.Request(
"https://api.alura.io/v1/workspace/customers?repeat=true&sort=-lifetime_value",
headers={
"Authorization": f"Bearer {os.environ['ALURA_API_KEY']}",
},
)
with urllib.request.urlopen(request) as response:
print(json.load(response)){
"object": "list",
"data": [
{
"object": "workspace.customer",
"id": "4242",
"shop_ids": [
"22841907",
"30577120"
],
"name": "Jane Example",
"image_url": null,
"location": {
"country": "US",
"city": "Portland"
},
"orders": 4,
"items": 5,
"first_order_at": "2025-11-02T15:20:00.000Z",
"last_order_at": "2026-10-05T18:45:00.000Z",
"repeat": true,
"lifetime_value": {
"amount": "138.40",
"currency": "USD",
"usd": "138.40"
},
"average_order_value": {
"amount": "34.60",
"currency": "USD",
"usd": "34.60"
},
"refunds": {
"count": 1,
"amount": {
"amount": "12.00",
"currency": "USD",
"usd": "12.00"
}
},
"reviews": {
"count": 3,
"average": 4.67
},
"as_of": "2026-10-08T06:00:00.000Z"
}
],
"has_more": false,
"next_cursor": null,
"total": {
"value": 1,
"relation": "eq"
},
"summary": {
"as_of": "2026-10-08T06:00:00.000Z",
"freshness": [
{
"shop_id": "22841907",
"as_of": "2026-10-08T06:00:00.000Z"
},
{
"shop_id": "30577120",
"as_of": "2026-10-17T06:00:00.000Z"
},
{
"shop_id": "48911633",
"as_of": "2026-10-16T06:00:00.000Z"
}
],
"notices": [
{
"code": "stale_shops",
"shop_ids": [
"22841907"
],
"detail": "These shops have no data, or no data newer than 7 days, for this area. Start a sync to refresh them."
},
{
"code": "lifetime_value_ranked_by_stored_total",
"shop_ids": [
"22841907",
"30577120",
"48911633"
],
"detail": "Ranked by the lifetime total Alura stored for each customer. A customer whose total Alura cannot verify against the stored orders keeps that rank with lifetime_value null; customers with no stored total come last."
}
],
"fx_as_of": "2026-10-17T00:00:00.000Z"
}
}{
"type": "https://docs.alura.io/errors/invalid_request",
"title": "Invalid request",
"status": 400,
"code": "invalid_request",
"detail": "Invalid request",
"suggestion": "Fix the request as the detail says, then send it again.",
"retryable": false,
"request_id": "req_01JQ5W3H8M2N4P6R8T0V2X4Z6B"
}{
"type": "https://docs.alura.io/errors/unauthorized",
"title": "Unauthorized",
"status": 401,
"code": "unauthorized",
"detail": "Unauthorized",
"suggestion": "Send a valid API key as `Authorization: Bearer alura_sk_...`.",
"retryable": false,
"request_id": "req_01JQ5W3H8M2N4P6R8T0V2X4Z6B"
}{
"type": "https://docs.alura.io/errors/credits_exhausted",
"title": "API credits exhausted",
"status": 402,
"code": "credits_exhausted",
"detail": "API credits exhausted",
"suggestion": "Upgrade the plan or wait for the monthly reset.",
"retryable": false,
"request_id": "req_01JQ5W3H8M2N4P6R8T0V2X4Z6B"
}{
"type": "https://docs.alura.io/errors/plan_required",
"title": "Plan required",
"status": 403,
"code": "plan_required",
"detail": "Plan required",
"suggestion": "Upgrade the workspace plan to use this operation.",
"retryable": false,
"request_id": "req_01JQ5W3H8M2N4P6R8T0V2X4Z6B"
}{
"type": "https://docs.alura.io/errors/not_found",
"title": "Not found",
"status": 404,
"code": "not_found",
"detail": "Not found",
"suggestion": "Check the ID, or search for it first.",
"retryable": false,
"request_id": "req_01JQ5W3H8M2N4P6R8T0V2X4Z6B"
}{
"type": "https://docs.alura.io/errors/method_not_allowed",
"title": "Method not allowed",
"status": 405,
"code": "method_not_allowed",
"detail": "Method not allowed",
"suggestion": "Use one of the methods in the Allow header.",
"retryable": false,
"request_id": "req_01JQ5W3H8M2N4P6R8T0V2X4Z6B"
}{
"type": "https://docs.alura.io/errors/rate_limited",
"title": "Rate limited",
"status": 429,
"code": "rate_limited",
"detail": "Rate limited",
"suggestion": "Wait for Retry-After, then retry.",
"retryable": true,
"request_id": "req_01JQ5W3H8M2N4P6R8T0V2X4Z6B"
}{
"type": "https://docs.alura.io/errors/internal_error",
"title": "Internal error",
"status": 500,
"code": "internal_error",
"detail": "Internal error",
"suggestion": "Retry; if it keeps failing, report the request_id.",
"retryable": true,
"request_id": "req_01JQ5W3H8M2N4P6R8T0V2X4Z6B"
}{
"type": "https://docs.alura.io/errors/credits_unavailable",
"title": "API credits unavailable",
"status": 503,
"code": "credits_unavailable",
"detail": "API credits unavailable",
"suggestion": "Retry shortly.",
"retryable": true,
"request_id": "req_01JQ5W3H8M2N4P6R8T0V2X4Z6B"
}Authorizations
An API key: Authorization: Bearer alura_sk_....
Query Parameters
Only these connected shops, comma-separated; default every connected shop of the workspace. A shop outside the workspace is 404.
Only customers with an order at or after this time (a date is midnight UTC).
^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}(:\d{2}(\.\d{1,3})?)?(Z|[+-]\d{2}:\d{2}))?$Only customers with an order before this time.
^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}(:\d{2}(\.\d{1,3})?)?(Z|[+-]\d{2}:\d{2}))?$lifetime_value, orders, last_order, first_order; prefix - for descending. Default -last_order. lifetime_value ranks by the lifetime total Alura stored for each customer, in USD at the request's exchange rates: a customer whose total Alura cannot verify against the stored orders keeps that rank with lifetime_value: null (the lifetime_value_ranked_by_stored_total notice says so), and customers with no stored total come last. orders ranks by the order count Alura stored for each customer, which may include canceled orders Etsy says were never paid (the served orders leaves those out). For the other sorts, customers whose value is unknown come last. Ties go by customer ID.
lifetime_value, orders, last_order, first_order, -lifetime_value, -orders, -last_order, -first_order "-lifetime_value"
true: only customers with 2 or more orders; false: only customers with one. By the order count Alura stored for each customer, which may include canceled orders Etsy says were never paid, so a customer's served repeat can differ.
true, false "true"
Page size: default 25, at most 100.
1 <= x <= 100The next_cursor of the previous page. Bound to the query, the workspace and the key.
Comma-separated dotted paths to return; id, object and as_of always come back.