curl -X POST "https://api.alura.io/v1/workspace/customers/search" \
-H "Authorization: Bearer $ALURA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"q":"Jane"}'const res = await fetch('https://api.alura.io/v1/workspace/customers/search', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.ALURA_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"q": "Jane"
}),
});
console.log(await res.json());import json
import os
import urllib.request
request = urllib.request.Request(
"https://api.alura.io/v1/workspace/customers/search",
method="POST",
data=json.dumps({
"q": "Jane"
}).encode(),
headers={
"Authorization": f"Bearer {os.environ['ALURA_API_KEY']}",
"Content-Type": "application/json",
},
)
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."
}
],
"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 by name or country
Searches the customers of your connected Etsy shops like GET /v1/workspace/customers, with every filter in the JSON body, plus q (a part of the customer’s name, case-insensitive) and country (where their orders ship). A POST because a name and a location are personal data and URLs are kept in request logs: they stay in the body. It reads only; nothing changes. cursor and limit go in the query string. 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 -X POST "https://api.alura.io/v1/workspace/customers/search" \
-H "Authorization: Bearer $ALURA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"q":"Jane"}'const res = await fetch('https://api.alura.io/v1/workspace/customers/search', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.ALURA_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"q": "Jane"
}),
});
console.log(await res.json());import json
import os
import urllib.request
request = urllib.request.Request(
"https://api.alura.io/v1/workspace/customers/search",
method="POST",
data=json.dumps({
"q": "Jane"
}).encode(),
headers={
"Authorization": f"Bearer {os.environ['ALURA_API_KEY']}",
"Content-Type": "application/json",
},
)
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."
}
],
"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
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.
Body
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 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.
Only customers whose orders ship to this country (ISO 3166-1 alpha-2), as stored on the customer row of the shop they ordered from last. That row keeps one ship-to per shop, not necessarily the latest order's, so a customer whose ship-to changed can be missed.
^[A-Za-z]{2}$A part of the customer's name (case-insensitive), as any of the selected shops stores it.