Skip to main content

Artist Orders API

The Artist Orders API allows artists to view and fulfill orders from the gallery. Artists can see orders containing their products, mark items as shipped, and provide tracking information.

Authentication

All artist endpoints require Supabase authentication:

Authorization: Bearer <access_token>

Additionally, Row Level Security (RLS) policies ensure artists only see their own orders.


Endpoints

List Artist Orders

Retrieves all gallery orders containing the artist's products.

Endpoint: GET /api/gallery/artist/orders

Authentication: Required (Supabase JWT)

Query Parameters:

ParameterTypeRequiredDescription
org_idstringYesArtist's organization UUID
statusstringNoFilter by status (paid, processing, shipped, delivered)
limitnumberNoMax results (default: 50, max: 100)
offsetnumberNoPagination offset (default: 0)

Response:

{
"orders": [
{
"id": "artist_order_001",
"parentOrder": {
"id": "order_abc123",
"publicId": "GAL-2024-ABC123",
"createdAt": "2024-01-15T10:30:00Z",
"paidAt": "2024-01-15T10:32:00Z"
},
"status": "paid",
"subtotal": 120.00,
"artistPayout": 105.60,
"items": [
{
"id": "item_001",
"productId": "prod_001",
"productName": "Abstract Painting #5",
"quantity": 2,
"price": 60.00,
"image": "https://...",
"product": {
"sku": "ABS-005",
"inventory": 10
}
}
],
"shippingAddress": {
"name": "John Doe",
"line1": "123 Main St",
"city": "New York",
"state": "NY",
"postal_code": "10001",
"country": "US"
},
"trackingNumber": null,
"trackingUrl": null,
"shippedAt": null
}
],
"pagination": {
"total": 15,
"limit": 50,
"offset": 0,
"hasMore": false
}
}

Response Fields:

FieldTypeDescription
ordersarrayArray of artist order objects
orders[].idstringArtist order UUID
orders[].parentOrderobjectParent gallery order info
orders[].statusstringOrder status
orders[].subtotalnumberTotal for this artist's items
orders[].artistPayoutnumberAmount artist receives (88% of subtotal)
orders[].itemsarrayLine items to fulfill
orders[].shippingAddressobjectWhere to ship (can be per-artist address)
orders[].trackingNumberstringTracking number (if shipped)
orders[].trackingUrlstringCarrier tracking URL (if shipped)
orders[].shippedAtstringISO 8601 timestamp (if shipped)
paginationobjectPagination metadata

Example Request:

curl https://gallery.artbase.studio/api/gallery/artist/orders?org_id=org_abc123 \
-H "Authorization: Bearer <token>"

Example with Filters:

curl "https://gallery.artbase.studio/api/gallery/artist/orders?org_id=org_abc123&status=paid&limit=20" \
-H "Authorization: Bearer <token>"

Error Responses:

StatusErrorDescription
400Organization ID requiredMissing org_id parameter
401UnauthorizedMissing or invalid token
403ForbiddenUser not member of organization

Mark Order as Shipped

Updates an artist order to shipped status with tracking information.

Endpoint: POST /api/gallery/artist/orders/{id}/ship

Authentication: Required (Supabase JWT)

URL Parameters:

ParameterTypeDescription
idstringArtist order UUID

Request Body:

{
"trackingNumber": "1Z999AA10123456784",
"carrier": "UPS"
}

Request Parameters:

FieldTypeRequiredDescription
trackingNumberstringYesShipment tracking number
carrierstringNoCarrier name ("UPS", "USPS", "FedEx", or custom)

Response:

{
"success": true,
"order": {
"id": "artist_order_001",
"status": "shipped",
"trackingNumber": "1Z999AA10123456784",
"trackingUrl": "https://www.ups.com/track?tracknum=1Z999AA10123456784",
"shippedAt": "2024-01-16T14:20:00Z"
},
"parentOrderStatus": "partially_shipped"
}

Response Fields:

FieldTypeDescription
successbooleanAlways true on success
orderobjectUpdated artist order
order.statusstringNow "shipped"
order.trackingNumberstringTracking number provided
order.trackingUrlstringAuto-generated tracking URL
order.shippedAtstringISO 8601 timestamp
parentOrderStatusstringUpdated parent order status

Example Request:

curl -X POST https://gallery.artbase.studio/api/gallery/artist/orders/artist_order_001/ship \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"trackingNumber": "1Z999AA10123456784",
"carrier": "UPS"
}'

Error Responses:

StatusErrorDescription
400Tracking number requiredMissing trackingNumber
401UnauthorizedMissing or invalid token
403ForbiddenArtist doesn't own this order
404Order not foundInvalid order ID
400Order already shippedCannot ship twice

Cascading Status Updates:

When an artist marks their order as shipped, the parent order status is recalculated:

// Parent status logic
const allArtistOrders = await getArtistOrdersForParent(parentOrderId);
const allShipped = allArtistOrders.every(ao =>
ao.status === 'shipped' || ao.status === 'delivered'
);
const anyShipped = allArtistOrders.some(ao =>
ao.status === 'shipped' || ao.status === 'delivered'
);

let newParentStatus;
if (allShipped) {
newParentStatus = 'shipped'; // All artists have shipped
} else if (anyShipped) {
newParentStatus = 'partially_shipped'; // Some artists shipped
} else {
newParentStatus = 'paid'; // None shipped yet
}

Tracking URL Generation:

The system auto-generates tracking URLs based on carrier:

CarrierURL Template
UPShttps://www.ups.com/track?tracknum={number}
USPShttps://tools.usps.com/go/TrackConfirmAction?tLabels={number}
FedExhttps://www.fedex.com/fedextrack/?trknbr={number}
CustomStored as provided (artist provides full URL)

Order Fulfillment Workflow

1. Receive Order Notification

When a customer completes checkout:

  • Artist receives email notification (sendArtistOrderNotificationEmail)
  • Email contains order details and items to ship
  • Artist logs into dashboard to view order

2. View Order Details

Artist calls GET /api/gallery/artist/orders?org_id={org_id}:

const response = await fetch(
`/api/gallery/artist/orders?org_id=${orgId}&status=paid`,
{
headers: {
Authorization: `Bearer ${token}`,
},
}
);
const { orders } = await response.json();

3. Prepare Items

Artist:

  • Locates items in inventory (using SKU if available)
  • Packs items securely
  • Prepares shipping label

4. Ship and Update Status

Artist calls POST /api/gallery/artist/orders/{id}/ship:

await fetch(`/api/gallery/artist/orders/${orderId}/ship`, {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
trackingNumber: '1Z999AA10123456784',
carrier: 'UPS',
}),
});

5. Customer Notification

System automatically:

  • Updates parent order status
  • Sends shipping notification email to customer (sendShippingNotificationEmail)
  • Displays tracking info on customer tracking page

6. Receive Payout

Artist receives payout automatically:

  • Timing: 2-7 business days after shipment (Stripe Standard payout)
  • Amount: 88% of subtotal
  • Destination: Artist's Stripe Connect account
  • Visibility: View in Stripe Dashboard

Inventory Management

Artists should track inventory to avoid overselling:

// When order received
async function handleNewOrder(order) {
for (const item of order.items) {
// Check inventory
const product = await getProduct(item.productId);
if (product.inventory < item.quantity) {
// Alert: insufficient inventory
await notifyArtist({
type: 'low_inventory',
product: product.name,
needed: item.quantity,
available: product.inventory,
});
}

// Reserve inventory
await updateProduct(item.productId, {
inventory: product.inventory - item.quantity,
});
}
}

// When order shipped
async function handleShipped(order) {
// Inventory already reserved, no action needed
console.log('Order shipped successfully');
}

Out of Stock Handling

If artist cannot fulfill:

  1. Contact customer - Use email from order
  2. Offer alternatives - Suggest similar products or refund
  3. Process refund - Contact gallery support for refund (manual process currently)

Shipping Best Practices

CarrierBest ForTracking Quality
UPSHigh-value items, insuranceExcellent
USPSLightweight, domesticGood
FedExFast delivery, commercialExcellent

Packaging Guidelines

  • Protect artwork: Use bubble wrap, cardboard corners
  • Weatherproof: Seal in plastic before boxing
  • Label clearly: Include return address
  • Insure valuable items: Purchase carrier insurance for items >$100

Shipping Timeline

Aim to ship within 1-3 business days of receiving order:

  • ⏱️ Same day: Exceptional service, happy customers
  • 1-2 days: Standard timeframe, good experience
  • ⚠️ 3-5 days: Acceptable but slow
  • >7 days: Too slow, contact customer to explain delay

Analytics Integration

Artists can track performance using the Analytics API:

const analytics = await fetch(
`/api/gallery/artist/analytics?org_id=${orgId}`,
{
headers: { Authorization: `Bearer ${token}` },
}
);

const data = await analytics.json();
console.log(`Total orders: ${data.totalOrders}`);
console.log(`Total revenue: $${data.totalRevenue}`);
console.log(`Artist payout: $${data.artistPayout}`);

See Artist Analytics API for details.


Testing

Test Flow

  1. Create test order: Use Stripe test card to create order
  2. View orders: Call GET /api/gallery/artist/orders to see new order
  3. Mark shipped: Call POST .../ship with test tracking number
  4. Verify status: Check parent order updated to partially_shipped or shipped

Test Data

Use these test tracking numbers:

{
"UPS": "1Z999AA10123456784",
"USPS": "9400111899562537883321",
"FedEx": "771234567890"
}

Next Steps