API v1 preview

# List models

`GET /api/v1/models`

## Overview

List the account's models, oldest update first, for synchronization. Filter by status, customer reference or update time; use sort=-created_at for newest first. Pages return data, has_more and next_cursor. Deleted models are omitted, even from updated_since results; use Get Model to confirm a missing ID. Listing does not start inspection or repair.

Requires `models:read`.

[Create and poll a model guide](https://ottomfg.com/docs/models.md)

[Errors and retries](https://ottomfg.com/docs/errors.md)

Request

```
# cURL: fetch one page using a server-side key with models:read.
curl --fail-with-body --get "${API_BASE_URL%/}/api/v1/models" \
  --header "Authorization: Bearer $OTTOMFG_API_KEY" \
  --data-urlencode "limit=20"
# If has_more is true, repeat with --data-urlencode "cursor=$NEXT_CURSOR",
# setting NEXT_CURSOR to the response's next_cursor. Keep filters unchanged.
# Optional filters: --data-urlencode "external_id=design-123"
# or --data-urlencode "updated_since=2026-09-21T00:00:00Z".
# Pages are live; deduplicate by id and updated_at when syncing.
# Optional status filter, e.g. ready,action_required (OR). Omit status for full synchronization.
```

Set API_BASE_URL and OTTOMFG_API_KEY. Use next_cursor to request the next page; keep filters unchanged.

[Registration and lookup examples](https://ottomfg.com/docs/models.md)

## Parameters

`sort` query · optional

updated_at sorts oldest update first, with ascending id ties. -created_at sorts newest creation first, with descending id ties. Repeat the same sort on every cursor request; cursors cannot be reused across sort orders.

string

Allowed values: updated_at, -created_at

`status` query · optional

Comma-separated model statuses (OR): processing, ready, action_required, failed. Filters combine with AND. Omit status for full synchronization.

array

`updated_since` query · optional

Inclusive lower bound on updated_at. Use an RFC 3339 timestamp with a timezone and at most six fractional digits. Repeat the same filters on subsequent pages.

string (date-time)

`external_id` query · optional

Exact, case-sensitive customer reference match. May return multiple models. An empty string matches an explicitly empty external_id, not an omitted field. Unicode category C characters are not accepted.

string

`limit` query · optional

Page size, default 20, maximum 100; repeat on subsequent pages.

integer

`cursor` query · optional

Opaque next_cursor from a previous response for the same account. Has no time-based expiry; repeat the original filters and limit. Pages are live, not a frozen snapshot. Concurrent updates may reappear; deduplicate by id and updated_at.

string

## Responses

A live page of account models. An empty library returns data: [], has_more: false and next_cursor: null.

200 response

```
{
  "data": [
    {
      "id": "MD-739YQ549",
      "source": {
        "file_id": "file_6c82bd3e319b4bb099310d54a761879e"
      },
      "name": "Wedding figurine",
      "external_id": "design-123",
      "created_at": "2026-09-18T18:00:00.000000Z",
      "updated_at": "2026-09-18T18:00:00.000000Z",
      "status": "processing",
      "status_reasons": [
        {
          "code": "inspection_pending",
          "message": "Mesh inspection is running."
        }
      ],
      "preview": null,
      "longest_dimension_mm": 100,
      "mesh_check": {
        "status": "pending"
      },
      "print_check": {
        "status": "pending"
      },
      "repair": {
        "required": false,
        "applied": false,
        "reason": null,
        "status": "not_applied",
        "fee": 0,
        "covered_by_order_id": null
      }
    }
  ],
  "has_more": false,
  "next_cursor": null
}
```

`data` array · required

Models in ascending updated_at and id order. Each item has the same fields as Get Model.

[Model object](https://ottomfg.com/docs/model-object.md)

`next_cursor` string | null · required

Pass as cursor on the next request. Null when no further page is currently available.

`has_more` boolean · required

Whether additional matching models were available when this page was read.

**Response headers**

`X-Request-ID`

Request identifier for support. Send X-Request-ID with 8–64 ASCII letters, digits or hyphens to reuse that value; otherwise the server generates a UUID4 hex value. Include the returned X-Request-ID in support requests. Do not put secrets or account IDs in this value.

## Errors

| HTTP | Code | What to do |
| --- | --- | --- |
| 400 Bad Request | `invalid_argument` | A field, query parameter or header is invalid. Fix the field named in details, then send the request again. |
| 401 Unauthorized | `unauthenticated` | The API key is missing, invalid or revoked. Send a valid business API key in Authorization: Bearer. |
| 403 Forbidden | `permission_denied` | The key lacks the endpoint's scope, or payments lack spending consent. Check the scope listed on the endpoint. |
| 429 Too Many Requests | `resource_exhausted` | A rate or account limit was reached. Wait at least Retry-After seconds, then retry. |
| 500 Internal Server Error | `internal` | The server failed unexpectedly. Retry with backoff; contact support with X-Request-ID if it persists. |
| 503 Service Unavailable | `unavailable` | A required service is briefly unavailable. Retry with backoff, reusing the same Idempotency-Key. |

[Idempotent requests](https://ottomfg.com/docs/idempotency.md)

API v1 preview

Source: https://ottomfg.com/docs/list-models
