foryn
FDeveloper PortalOcean API v1

OPENAPI 3.1.0 / HTTP V1

API reference

Three implemented operations, with schemas generated from the canonical Zod intake contracts. Auth requires a provisioned integration credential.

POST/api/ocean/v1/bookings

Submit a qualified booking or update

Requires intake scope. The authenticated credential determines tenant and source. A 200 response may indicate ACCEPTED, EXCEPTION, INSUFFICIENT_EVIDENCE, OUT_OF_COVERAGE, DUPLICATE_EVENT, UNCHANGED_SNAPSHOT, STALE_REVISION, NOT_QUALIFIED or CANCELLED. Never infer financial exposure from null fields.

Request body

FieldType and constraintsRequired
schemaVersionstringYes
eventIdstring · min 1 · max 160Yes
revisionintegerYes
actionstring · enum: CONFIRMED, AMENDED, CANCELLEDYes
sourceBookingIdstring · min 1 · max 160Yes
bookingobjectNo
sourceobjectYes
CODE / EXAMPLE
{
  "schemaVersion": "foryn.ocean.booking.v1",
  "eventId": "synthetic-event-0001",
  "revision": 1,
  "action": "CONFIRMED",
  "sourceBookingId": "synthetic-source-booking-001",
  "booking": {
    "carrierBookingReference": "SYNTHETIC-CBR-001",
    "carrierId": "fictional-carrier",
    "originUnlocode": "CNSHG",
    "destinationUnlocode": "USLAX",
    "bookingDate": "2026-10-12",
    "equipmentType": "40HC",
    "quantity": 2,
    "commodity": "GENERAL",
    "namedAccountId": "account-1",
    "agreementReference": "agreement-1",
    "serviceType": "contract",
    "qualification": {
      "milestone": "CARRIER_CONFIRMED",
      "confirmedAt": "2026-10-12T12:00:00.000Z",
      "sourceEvidenceId": "synthetic-confirmation-001"
    }
  },
  "source": {
    "recordId": "synthetic-source-row-1",
    "documentId": "fictional-booking-document",
    "documentVersion": "1"
  }
}

HTTP responses

HTTPMeaning
200Delivery accepted for processing; inspect data.status and data.assessment.
400Malformed or invalid JSON payload
401No valid bearer token
403Revoked credential or insufficient intake scope
409Event identity, revision or booking identity conflict
413Request exceeds 64 KiB
415JSON content type required
429Rate limit exceeded or too many failed authentications; honor the Retry-After header
503Intake persistence unavailable, or the Ocean API is not enabled in this environment

For nested schemas, enumerations and exact response validation, use the linked OpenAPI JSON.

POST/api/ocean/v1/messages

Submit a supported EDI profile or partial booking extract

JSON wrapper around X12 301 MSC 005030, EDIFACT IFTMBC MSC D.99B or a partial canonical events extract. DCSA_BOOKING_2_0_0 is explicitly UNSUPPORTED. Each batch record is validated independently; no omission-based cancellation.

Request body

See the machine-readable OpenAPI schema for nested variants and constraints.

CODE / EXAMPLE
{
  "format": "FORYN_EXTRACT_EVENTS_V1",
  "snapshotKind": "PARTIAL",
  "records": [
    {
      "schemaVersion": "foryn.ocean.booking.v1",
      "eventId": "synthetic-event-0001",
      "revision": 1,
      "action": "CONFIRMED",
      "sourceBookingId": "synthetic-source-booking-001",
      "booking": {
        "carrierBookingReference": "SYNTHETIC-CBR-001",
        "carrierId": "fictional-carrier",
        "originUnlocode": "CNSHG",
        "destinationUnlocode": "USLAX",
        "bookingDate": "2026-10-12",
        "equipmentType": "40HC",
        "quantity": 2,
        "commodity": "GENERAL",
        "namedAccountId": "account-1",
        "agreementReference": "agreement-1",
        "serviceType": "contract",
        "qualification": {
          "milestone": "CARRIER_CONFIRMED",
          "confirmedAt": "2026-10-12T12:00:00.000Z",
          "sourceEvidenceId": "synthetic-confirmation-001"
        }
      },
      "source": {
        "recordId": "synthetic-source-row-1",
        "documentId": "fictional-booking-document",
        "documentVersion": "1"
      }
    },
    {
      "schemaVersion": "foryn.ocean.booking.v1",
      "eventId": "invalid-fixture",
      "revision": 1,
      "action": "CONFIRMED",
      "sourceBookingId": "synthetic-source-booking-001",
      "booking": {
        "carrierBookingReference": "SYNTHETIC-CBR-001",
        "carrierId": "fictional-carrier",
        "originUnlocode": "CNSHG",
        "destinationUnlocode": "USLAX",
        "bookingDate": "2026-10-12",
        "equipmentType": "40HC",
        "quantity": 0,
        "commodity": "GENERAL",
        "namedAccountId": "account-1",
        "agreementReference": "agreement-1",
        "serviceType": "contract",
        "qualification": {
          "milestone": "CARRIER_CONFIRMED",
          "confirmedAt": "2026-10-12T12:00:00.000Z",
          "sourceEvidenceId": "synthetic-confirmation-001"
        }
      },
      "source": {
        "recordId": "synthetic-source-row-1",
        "documentId": "fictional-booking-document",
        "documentVersion": "1"
      }
    }
  ]
}

HTTP responses

HTTPMeaning
200Message mapping status or a per-record partial extract response
400Malformed message or invalid JSON wrapper
401Missing or invalid credential
403Credential not authorized
409Canonical booking returned a conflict; outer adapter envelope remains ok:true, nested bookingResponse contains ApiError.
413Request exceeds 64 KiB
415JSON content type required
429Rate limit exceeded or too many failed authentications; honor the Retry-After header
503Canonical intake unavailable; inspect nested bookingResponse when a mapped message was submitted.

For nested schemas, enumerations and exact response validation, use the linked OpenAPI JSON.

POST/api/ocean/v1/exceptions/{exceptionId}/resolutions

Record an optional resolution or explanation

Requires separate resolution scope. Actor reference is asserted by the source system, not a Foryn human login. Only exceptions belonging to the authenticated tenant are accessible.

exceptionId: Opaque tenant-scoped exception ID returned by a consequential booking assessment

Request body

FieldType and constraintsRequired
schemaVersionstringYes
eventIdstring · min 1 · max 160Yes
statusstring · enum: RESOLVED, NOT_RESOLVED, DISPUTEDYes
reasonCodestring · min 1 · max 160Yes
explanationstring · max 2000No
actorReferencestring · min 1 · max 160Yes
occurredAtstring · pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ · format date-timeYes
CODE / EXAMPLE
{
  "schemaVersion": "foryn.ocean.resolution.v1",
  "eventId": "synthetic-resolution-1",
  "status": "RESOLVED",
  "reasonCode": "REVIEWED_BY_REGIONAL_OPS",
  "explanation": "Source account restriction reviewed.",
  "actorReference": "source-operator-1",
  "occurredAt": "2026-10-16T12:00:00.000Z"
}

HTTP responses

HTTPMeaning
200Resolution recorded or exact idempotent retry
400Invalid body or exception ID
401Missing bearer credential
403Resolution scope missing
404Exception absent from authenticated tenant
409Resolution event ID reused with different content
413Request exceeds 64 KiB
415JSON content type required
429Rate limit exceeded or too many failed authentications; honor the Retry-After header
503Resolution persistence unavailable, or the Ocean API is not enabled in this environment

For nested schemas, enumerations and exact response validation, use the linked OpenAPI JSON.