Skip to content

Objects

Endpoints for managing objects (files) within datasets. Objects go through a three-step upload flow before they are available for search and retrieval.

Three-step upload flow

Uploading an object to IPTO follows three steps:

  1. Initiate -- Call POST /v1/datasets/{dataset_id}/objects/upload to get a pre-signed upload URL.
  2. Upload -- PUT the file bytes directly to the returned upload_url (this goes to object storage, not the IPTO API).
  3. Confirm -- Call POST /v1/objects/{id}/confirm to finalize the upload and submit the object for admin review.

Until an object is confirmed and approved by an admin, it will not appear in search results.


Initiate Upload

Request a pre-signed upload URL for a new object in a dataset.

POST /v1/datasets/{dataset_id}/objects/upload

Authentication: Authorization: Bearer {token} or X-API-Key: ipto_{prefix}_{secret}

Scope: objects:write

Request

curl -X POST https://api.ipto.ai/v1/datasets/dset_a1b2c3d4e5f6/objects/upload \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "filename": "invoice-0425.pdf",
    "content_type": "application/pdf",
    "size_bytes": 812345
  }'
import requests

response = requests.post(
    "https://api.ipto.ai/v1/datasets/dset_a1b2c3d4e5f6/objects/upload",
    headers={"Authorization": "Bearer {token}"},
    json={
        "filename": "invoice-0425.pdf",
        "content_type": "application/pdf",
        "size_bytes": 812345,
    },
)
data = response.json()
const response = await fetch(
  "https://api.ipto.ai/v1/datasets/dset_a1b2c3d4e5f6/objects/upload",
  {
    method: "POST",
    headers: {
      Authorization: "Bearer {token}",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      filename: "invoice-0425.pdf",
      content_type: "application/pdf",
      size_bytes: 812345,
    }),
  }
);
const data = await response.json();

Parameters

Field Type Required Description
dataset_id string Yes The dataset ID (path parameter).

Request Body

Field Type Required Description
filename string Yes Original filename of the object being uploaded.
content_type string Yes MIME type of the file (e.g., application/pdf, text/csv).
size_bytes integer Yes Size of the file in bytes.

Response

{
  "data": {
    "object_id": "obj_x1y2z3w4v5u6",
    "upload_url": "https://storage.ipto.ai/uploads/obj_x1y2z3w4v5u6?X-Amz-Signature=...",
    "expires_at": "2026-04-05T11:00:00Z"
  },
  "request_id": "req_obj001",
  "timestamp": "2026-04-05T10:00:00Z"
}

Response Fields

Field Type Description
object_id string Unique identifier for the new object.
upload_url string Pre-signed URL to upload the file bytes via PUT.
expires_at string ISO 8601 timestamp after which the upload URL is no longer valid.

Upload the file bytes

After receiving the upload_url, upload the file using a PUT request directly to that URL. Do not include IPTO authentication headers -- the URL is pre-signed.

curl -X PUT "{upload_url}" \
  -H "Content-Type: application/pdf" \
  --data-binary @invoice-0425.pdf

Confirm Upload

Confirm that the file has been uploaded to object storage and submit the object for admin review.

POST /v1/objects/{id}/confirm

Authentication: Authorization: Bearer {token} or X-API-Key: ipto_{prefix}_{secret}

Scope: objects:write

Request

curl -X POST https://api.ipto.ai/v1/objects/obj_x1y2z3w4v5u6/confirm \
  -H "Authorization: Bearer {token}"
import requests

response = requests.post(
    "https://api.ipto.ai/v1/objects/obj_x1y2z3w4v5u6/confirm",
    headers={"Authorization": "Bearer {token}"},
)
data = response.json()
const response = await fetch(
  "https://api.ipto.ai/v1/objects/obj_x1y2z3w4v5u6/confirm",
  {
    method: "POST",
    headers: { Authorization: "Bearer {token}" },
  }
);
const data = await response.json();

Parameters

Field Type Required Description
id string Yes The object ID (path parameter).

Response

{
  "data": {
    "object_id": "obj_x1y2z3w4v5u6",
    "dataset_id": "dset_a1b2c3d4e5f6",
    "filename": "invoice-0425.pdf",
    "content_type": "application/pdf",
    "size_bytes": 812345,
    "checksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
    "status": "staged",
    "review_state": "pending",
    "uploaded_at": "2026-04-05T10:01:00Z",
    "review_expires_at": "2026-04-12T10:01:00Z",
    "reviewed_at": null
  },
  "request_id": "req_obj002",
  "timestamp": "2026-04-05T10:01:00Z"
}

Response Fields

Field Type Description
object_id string Unique identifier for the object.
dataset_id string Identifier of the parent dataset.
filename string Original filename.
content_type string MIME type of the file.
size_bytes integer File size in bytes.
checksum_sha256 string SHA-256 checksum of the uploaded file.
status string Object pipeline status (e.g., staged, active, deleted).
review_state string Admin review state (pending, approved, rejected).
uploaded_at string ISO 8601 timestamp when the upload was confirmed.
review_expires_at string \| null ISO 8601 deadline for admin review.
reviewed_at string \| null ISO 8601 timestamp when the object was reviewed, or null.

Cancel Upload

Cancel a pending upload that has not yet been confirmed. Cleans up the pre-signed URL and any partial upload state.

DELETE /v1/objects/{id}/upload

Authentication: Authorization: Bearer {token} or X-API-Key: ipto_{prefix}_{secret}

Scope: objects:write

Request

curl -X DELETE https://api.ipto.ai/v1/objects/obj_x1y2z3w4v5u6/upload \
  -H "Authorization: Bearer {token}"
import requests

response = requests.delete(
    "https://api.ipto.ai/v1/objects/obj_x1y2z3w4v5u6/upload",
    headers={"Authorization": "Bearer {token}"},
)
data = response.json()
const response = await fetch(
  "https://api.ipto.ai/v1/objects/obj_x1y2z3w4v5u6/upload",
  {
    method: "DELETE",
    headers: { Authorization: "Bearer {token}" },
  }
);
const data = await response.json();

Parameters

Field Type Required Description
id string Yes The object ID (path parameter).

Response

{
  "data": {},
  "request_id": "req_obj003",
  "timestamp": "2026-04-05T10:02:00Z"
}

Response Fields

Returns an empty object on success.


List Objects

List objects within a specific dataset.

GET /v1/datasets/{dataset_id}/objects

Authentication: Authorization: Bearer {token} or X-API-Key: ipto_{prefix}_{secret}

Scope: datasets:read

Request

curl -X GET "https://api.ipto.ai/v1/datasets/dset_a1b2c3d4e5f6/objects?limit=20" \
  -H "Authorization: Bearer {token}"
import requests

response = requests.get(
    "https://api.ipto.ai/v1/datasets/dset_a1b2c3d4e5f6/objects",
    headers={"Authorization": "Bearer {token}"},
    params={"limit": 20},
)
data = response.json()
const response = await fetch(
  "https://api.ipto.ai/v1/datasets/dset_a1b2c3d4e5f6/objects?limit=20",
  {
    headers: { Authorization: "Bearer {token}" },
  }
);
const data = await response.json();

Parameters

Field Type Required Description
dataset_id string Yes The dataset ID (path parameter).
cursor string No Opaque pagination cursor from a previous response.
limit integer No Maximum number of objects to return. Default: 20.
status string No Filter by object status (e.g., staged, active, deleted).

Response

{
  "data": {
    "objects": [
      {
        "object_id": "obj_x1y2z3w4v5u6",
        "dataset_id": "dset_a1b2c3d4e5f6",
        "filename": "invoice-0425.pdf",
        "content_type": "application/pdf",
        "size_bytes": 812345,
        "checksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
        "status": "active",
        "review_state": "approved",
        "uploaded_at": "2026-04-05T10:01:00Z",
        "review_expires_at": "2026-04-12T10:01:00Z",
        "reviewed_at": "2026-04-05T14:00:00Z"
      }
    ],
    "total": 1
  },
  "request_id": "req_obj004",
  "timestamp": "2026-04-05T14:05:00Z"
}

Response Fields

Field Type Description
objects Object[] Array of object records. See Confirm Upload for field definitions.
total integer Total number of objects matching the query.

Get Object

Retrieve metadata for a single object.

GET /v1/objects/{id}

Authentication: Authorization: Bearer {token} or X-API-Key: ipto_{prefix}_{secret}

Scope: datasets:read

Request

curl -X GET https://api.ipto.ai/v1/objects/obj_x1y2z3w4v5u6 \
  -H "Authorization: Bearer {token}"
import requests

response = requests.get(
    "https://api.ipto.ai/v1/objects/obj_x1y2z3w4v5u6",
    headers={"Authorization": "Bearer {token}"},
)
data = response.json()
const response = await fetch(
  "https://api.ipto.ai/v1/objects/obj_x1y2z3w4v5u6",
  {
    headers: { Authorization: "Bearer {token}" },
  }
);
const data = await response.json();

Parameters

Field Type Required Description
id string Yes The object ID (path parameter).

Response

{
  "data": {
    "object_id": "obj_x1y2z3w4v5u6",
    "dataset_id": "dset_a1b2c3d4e5f6",
    "filename": "invoice-0425.pdf",
    "content_type": "application/pdf",
    "size_bytes": 812345,
    "checksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
    "status": "active",
    "review_state": "approved",
    "uploaded_at": "2026-04-05T10:01:00Z",
    "review_expires_at": "2026-04-12T10:01:00Z",
    "reviewed_at": "2026-04-05T14:00:00Z"
  },
  "request_id": "req_obj005",
  "timestamp": "2026-04-05T14:05:00Z"
}

Response Fields

See Confirm Upload for the full list of object fields.


Download Object

Get a time-limited download URL for the original file.

GET /v1/objects/{id}/download

Authentication: Authorization: Bearer {token} or X-API-Key: ipto_{prefix}_{secret}

Scope: datasets:read

Request

curl -X GET https://api.ipto.ai/v1/objects/obj_x1y2z3w4v5u6/download \
  -H "Authorization: Bearer {token}"
import requests

response = requests.get(
    "https://api.ipto.ai/v1/objects/obj_x1y2z3w4v5u6/download",
    headers={"Authorization": "Bearer {token}"},
)
data = response.json()
const response = await fetch(
  "https://api.ipto.ai/v1/objects/obj_x1y2z3w4v5u6/download",
  {
    headers: { Authorization: "Bearer {token}" },
  }
);
const data = await response.json();

Parameters

Field Type Required Description
id string Yes The object ID (path parameter).

Response

{
  "data": {
    "download_url": "https://storage.ipto.ai/downloads/obj_x1y2z3w4v5u6?X-Amz-Signature=...",
    "expires_at": "2026-04-05T15:00:00Z"
  },
  "request_id": "req_obj006",
  "timestamp": "2026-04-05T14:00:00Z"
}

Response Fields

Field Type Description
download_url string Pre-signed URL to download the file.
expires_at string ISO 8601 timestamp after which the download URL expires.

Download URL expiry

Download URLs are valid for a limited time (typically one hour). Generate a new URL if the previous one has expired.


Delete Object

Permanently delete an object. Creates a tombstone record and enqueues index cleanup.

DELETE /v1/objects/{id}

Authentication: Authorization: Bearer {token} or X-API-Key: ipto_{prefix}_{secret}

Scope: objects:write

Request

curl -X DELETE https://api.ipto.ai/v1/objects/obj_x1y2z3w4v5u6 \
  -H "Authorization: Bearer {token}"
import requests

response = requests.delete(
    "https://api.ipto.ai/v1/objects/obj_x1y2z3w4v5u6",
    headers={"Authorization": "Bearer {token}"},
)
data = response.json()
const response = await fetch(
  "https://api.ipto.ai/v1/objects/obj_x1y2z3w4v5u6",
  {
    method: "DELETE",
    headers: { Authorization: "Bearer {token}" },
  }
);
const data = await response.json();

Parameters

Field Type Required Description
id string Yes The object ID (path parameter).

Response

{
  "data": {},
  "request_id": "req_obj007",
  "timestamp": "2026-04-05T15:00:00Z"
}

Response Fields

Returns an empty object on success.

Eventual consistency

After deletion, the object may still appear in search results for a short period while index cleanup is processed. The original bytes are not immediately purged from storage.