Skip to main content

Overview

By default, the Arcus API returns only references (UUIDs) for related resources. Use ?expand[]=<field> to hydrate those references inline in a single request, eliminating N+1 API calls. This is identical to Stripe’s expand behavior.

Basic usage

# Without expand: order.customer is just an account_id UUID
curl "https://api.arcuserp.com/v1/entities/$ARCUS_ENTITY_ID/orders/ord_01H..." \
  -H "Authorization: Bearer $ARCUS_API_KEY"

# With expand: order.customer is the full account object
curl "https://api.arcuserp.com/v1/entities/$ARCUS_ENTITY_ID/orders/ord_01H...?expand[]=customer" \
  -H "Authorization: Bearer $ARCUS_API_KEY"

Response comparison

{
  "id": "ord_01H...",
  "object": "order",
  "account_id": "acc_01H...",
  "document_type": "sales_order",
  "status": "confirmed"
}
{
  "id": "ord_01H...",
  "object": "order",
  "account_id": "acc_01H...",
  "customer": {
    "id": "acc_01H...",
    "object": "account",
    "name": "Acme Corp",
    "account_type": "business",
    "email": "billing@acmecorp.example"
  },
  "document_type": "sales_order",
  "status": "confirmed"
}

Multiple expansions

Pass expand[] multiple times to hydrate multiple fields:
curl "https://api.arcuserp.com/v1/entities/$ARCUS_ENTITY_ID/orders/ord_01H...?expand[]=customer&expand[]=line_items.product" \
  -H "Authorization: Bearer $ARCUS_API_KEY"

Nested expansion

Use dot notation to expand nested relations (up to 4 levels deep):
# Expand the product inside each line item
?expand[]=line_items.product

# Expand the default vendor on each product inside each line item
?expand[]=line_items.product.default_vendor

List endpoints: the data. prefix

On list endpoints, all expand paths require the data. prefix:
# Single-resource endpoint: no prefix
GET /v1/entities/{entity_id}/orders/ord_01H...?expand[]=customer

# List endpoint: data. prefix required
GET /v1/entities/{entity_id}/orders?expand[]=data.customer&expand[]=data.line_items.product
Omitting the data. prefix on a list endpoint returns 400 Bad Request with code: invalid_expand_list_requires_data_prefix.

Limits

ConstraintValue
Max expand paths per request10
Max nesting depth4
Max hydrated rows per relation100 (returns reference + truncated: true beyond that)

Scope requirements

Each expand path requires the corresponding read scope on your API key. For example, expanding customer on an order requires the accounts:read scope. Missing scope returns 403 Forbidden with code: insufficient_scope and required: accounts:read.

SDK usage

const order = await arcus.orders.retrieve('ord_01H...', {
  expand: ['customer', 'line_items.product'],
});

// order.customer is now the full account object
console.log(order.customer.name);
order = arcus.orders.retrieve(
    'ord_01H...',
    expand=['customer', 'line_items.product'],
)
print(order.customer.name)
order, err := client.Orders.Get(ctx, "ord_01H...", &arcus.OrderGetParams{
    Expand: []string{"customer", "line_items.product"},
})
fmt.Println(order.Customer.Name)

Available expand paths per resource

Valid expand paths are documented on each endpoint’s reference page under the Expandable fields section. Requesting an invalid path returns 400 Bad Request with code: invalid_expand_unknown_field and a list of valid paths.