Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.offloadapi.com/llms.txt

Use this file to discover all available pages before exploring further.

A case is one tracked workflow against one counterparty. The current implementation stores it in DynamoDB, processes it asynchronously, and updates it as the thread evolves.

Core Fields

FieldWhat it means in the implementation
caseIdA random UUID generated when the case is created.
clientReferenceIdYour own identifier. Offload stores it and echoes it in GET /cases/{id} and webhook payloads.
channelValidated as EMAIL or SMS, but the workflow is currently email-based. Use EMAIL.
goalThe business outcome Offload is trying to achieve. objective is required. knowledge can be a string or an object.
counterpartyThe person or team Offload contacts. address and name are required.
senderPersonaHow Offload should represent your side of the conversation. name is required.
constraintsExtra instructions the worker passes into the LLM prompt.
resultSchemaAn optional object describing the shape of the final result. The API only validates that it is an object.
metadataOpaque JSON stored on the case and echoed in webhook payloads. It is not currently returned by GET /cases/{id}.
clientWebhookUrlOptional URL for outbound webhook delivery.

Runtime Fields

FieldRuntime meaning
statusOne of CREATED, RUNNING, INPUT_NEEDED, COMPLETED, FAILED.
attemptCountNumber of outbound messages sent so far. After the initial outreach succeeds, this becomes 1.
maxAttemptsMaximum number of automated follow-up attempts after the initial outreach.
nextActionAtUnix timestamp in milliseconds for the next scheduled check or follow-up. When nothing is scheduled, the implementation uses 253402300799999.
attachmentsInbound attachments seen on the case thread. Each entry is metadata only. Download URLs are minted separately.
resultStatusA workflow outcome string such as goal_achieved, max_retries, failed_rejected, BOUNCED, COMPLAINED, or REJECTED. Treat this as an open set.
resultStructured JSON extracted when the case completes successfully.
failureReasonPresent on some failures, especially provider delivery failures or explicit rejection-style outcomes.
inputRequestActive human-in-the-loop question, if the case is paused.
inputRequestIdStable identifier for the active input request.
inputRequestStatusPENDING, RESOLVED, or NONE.

Defaults

If you omit them at creation time:
  • maxAttempts defaults to 3
  • followUpDelayHours defaults to 72
That means a default case can send:
  • 1 initial outreach
  • up to 3 automated follow-ups

Attachments

Attachments are tracked separately from result:
  • they come from inbound reply events
  • they are stored as metadata on the case
  • they appear in webhook payloads and GET /cases/{id}
  • you fetch a fresh downloadUrl with GET /cases/{id}/attachments/{attachmentId}
The current implementation does not inspect attachment contents directly.

Usage Limits

POST /cases checks monthly usage before creating a new case:
  • SANDBOX: 100
  • PAYG: 100
  • BASE_PRO: 500
The limit compares both:
  • created cases in the current UTC month
  • billable finished cases in the current UTC month
The code treats completed cases as billable. Failed cases are billable unless the terminal resultStatus is BOUNCED, REJECTED, or COMPLAINED.

Design Advice

Good cases are:
  • specific
  • bounded to one outcome
  • easy to verify from the conversation
Good examples:
  • “Collect a signed W-9 from the vendor.”
  • “Confirm whether the Tuesday delivery window works.”
  • “Get the corrected March invoice.”
Poor examples:
  • “Handle vendor onboarding.”
  • “Figure out what to do.”
  • “Manage all communication with this account forever.”