Skip to main content
For production batch jobs, place the input file in private object storage and give Sutro a time-limited HTTPS download URL. The SDK forwards the URL instead of loading the file or including every row in the submission request. Amazon S3, Cloudflare R2, Google Cloud Storage, and other S3-compatible stores can all work. Sutro does not use your cloud credentials or storage API; it performs an ordinary HTTPS GET with the signed URL.

Input contract

Treat a presigned URL like a temporary credential. It is reusable until it expires or is otherwise invalidated. Do not commit it, put it in a job name or description, or write the complete URL to application logs. Redact the entire query string in logs and error-reporting tools.
Sutro currently makes one full-object GET and does not resume or retry a failed input download. For Amazon S3, expiration is checked when the request starts, and a URL can expire earlier than ExpiresIn when its temporary credentials or a bucket-policy restriction expires. See AWS’s expiration guidance.

Prepare a Parquet input

For standalone model inference, create a prompt column. Other columns are not sent to the model or copied into results. Sutro converts the selected cells to strings; null and NaN values become empty prompts, and embedded line breaks become the literal \n sequence.
Keep the exact source object until you reconcile the results. Sutro preserves input order, so join results by row position. A stable identifier such as record_id makes your pipeline easier to audit, although unused columns are not copied into standalone-model results. For a Sutro Function, columns must instead match the Function’s declared inputs. Required columns must exist; missing optional columns and extra columns are allowed. Values become strings and nulls become empty strings, so validate domain-specific values before submission.

Sign an Amazon S3 input

In production, use separate AWS identities for producing the object and signing read access:
  • The producer needs s3:PutObject. For a customer-managed AWS KMS key, single-part upload also needs kms:GenerateDataKey; multipart upload needs both kms:GenerateDataKey and kms:Decrypt.
  • The read-only signer needs s3:GetObject or, when signing a specific version, s3:GetObjectVersion. For a customer-managed AWS KMS key, it also needs kms:Decrypt. Prefer short-lived role credentials whose session remains valid for the URL lifetime.
The producer should upload to a unique key and record the version ID when bucket versioning is enabled. The following signing step assumes a versioned bucket and a signer authenticated with the read-only identity:
Including VersionId pins the URL to the uploaded version. Otherwise, use a unique key for every run and never overwrite it. Keep all four S3 Block Public Access settings enabled.

Use R2, Google Cloud Storage, or another provider

The same input contract applies to other object stores: Provider-specific expiration, permission, encryption, and versioning rules still apply. Keep the object private and immutable, give the signing identity read access only, and test the exact URL before submitting the full job.

Submit a standalone model job

Pass the URL as data. The SDK forwards it to Sutro instead of downloading the object locally.
Always specify column for standalone-model production jobs. Otherwise Sutro uses the first column, which can silently change when an upstream schema is reordered.
The POST /batch-inference response only confirms that the job was created. Download and quota validation happen asynchronously. Keep access valid while the worker begins and performs its one full-object GET.

Submit a Sutro Function job

When the object contains columns matching a published Function’s inputs, call the same batch runtime through infer() and use the Function name as model:
Do not pass column, system_prompt, or output_schema for this form. Sutro reads the Function input columns and uses the prompt and output schema from the published Function.
infer() defaults to truncate_rows=True; set it to False if an oversized rendered prompt should fail instead. This URL-based path cannot create the SDK’s per-row LangSmith traces because the SDK never downloads the rows.
The bounded Parquet tokenization path currently applies only to standalone-model jobs. Presigned URLs keep Function submissions and SDK memory small, but Function ingestion materializes the input after download. Split very large Function inputs into independently submitted objects.

Estimate, monitor, and retrieve results

Check the priority-1 row and token quotas, run a small canary, and create an estimate before the full workload:
dry_run=True creates an estimate job, prints its estimate, and returns its ID without launching the full job. Priority-1 estimates at or above the sampling threshold run inference on a prefix of approximately 1 million input tokens. Persist the full job’s ID before doing other work. Job creation is not idempotent. The SDK deliberately does not retry POST /batch-inference after an HTTP 524 because the job might already have been created. Do not add a blind outer retry loop; after an ambiguous response, inspect recent jobs before resubmitting.
obtain_results=False avoids materializing results as JSON but returns None regardless of outcome. Confirm SUCCEEDED before requesting GET /jobs/{job_id}/results-url?format=parquet and downloading urls.get. That endpoint supports resumable range requests; see Presigned Results URLs. For smaller jobs, see Retrieving Results. Results preserve the original input order. Keep the source object available until you have downloaded and reconciled the result artifact.

Troubleshooting

If the full-object GET fails, inspect the original job before generating a fresh URL and submitting a replacement. Standalone-model URL jobs mirror the raw source into Sutro-managed object storage before tokenization; the mirror and derived artifacts follow your configured data retention policy. The original object remains under your provider’s lifecycle policy.