Skip to Content
DocsAPIOpenapiRgl8r Public API V1.1.0

Rgl8r Public API V1.1.0

Source: docs/api/openapi/rgl8r-public-api-v1.1.0.yaml

openapi: 3.1.0 info: title: RGL8R Public API version: 1.1.0 summary: Public API contract for integration-key clients and AI agents. description: | Versioned contract for the public integration surface used by no-code automations, CI pipelines, and AI agents. Included surfaces: - Public self-serve signup session lifecycle - Public billing setup session bootstrap - Integration-key token exchange - Async job polling - SIMA screening queue + reporting - Upload enqueue endpoints Compatibility policy is defined in docs/api/public-api-contract-v1.md. servers: - url: https://api.rgl8r.com description: Production - url: https://rgl8r-staging-api.onrender.com description: Staging security: - bearerAuth: [] tags: - name: Auth description: Authenticate integration-key clients and issue short-lived bearer tokens. - name: Public Signup description: Unauthenticated signup bootstrap and resumable tenant provisioning. - name: Billing description: Billing setup and payment-method bootstrap for authenticated tenant integrations. - name: Jobs description: Poll asynchronous processing state across upload and screening workflows. - name: Trade Screening description: Run SIMA screening and retrieve outcomes, evidence, summaries, and exports. - name: Uploads description: Enqueue CSV/Excel files for trade, catalog, ship, order, and carrier workflows. paths: /api/public/signup/sessions: post: tags: [Public Signup] operationId: createPublicSignupSession summary: Create a self-serve signup session and send OTP email security: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/PublicSignupSessionCreateRequest' responses: '201': description: Signup session created content: application/json: schema: $ref: '#/components/schemas/PublicSignupSessionCreateResponse' '400': $ref: '#/components/responses/InvalidRequestError' '429': $ref: '#/components/responses/RateLimitedError' '503': $ref: '#/components/responses/FeatureDisabledError' '500': $ref: '#/components/responses/InternalError' /api/public/signup/sessions/{sessionId}/verify-email: post: tags: [Public Signup] operationId: verifyPublicSignupSessionEmail summary: Verify signup OTP and advance session to EMAIL_VERIFIED security: [] parameters: - name: sessionId in: path required: true schema: type: string format: uuid requestBody: required: true content: application/json: schema: type: object required: [code] properties: code: type: string pattern: '^\d{6}$' responses: '200': description: Session email verified content: application/json: schema: $ref: '#/components/schemas/PublicSignupSessionStatusResponse' '400': $ref: '#/components/responses/InvalidRequestError' '404': $ref: '#/components/responses/NotFoundError' '429': $ref: '#/components/responses/RateLimitedError' '503': $ref: '#/components/responses/FeatureDisabledError' '500': $ref: '#/components/responses/InternalError' /api/public/signup/sessions/{sessionId}/provision: post: tags: [Public Signup] operationId: provisionPublicSignupSession summary: Provision tenant resources with resumable state-machine semantics security: [] parameters: - name: sessionId in: path required: true schema: type: string format: uuid requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/PublicSignupProvisionRequest' responses: '201': description: Provisioning completed content: application/json: schema: $ref: '#/components/schemas/PublicSignupProvisionResponse' '202': description: Provisioning in-progress or manual-review path content: application/json: schema: $ref: '#/components/schemas/PublicSignupProvisionResponse' '400': $ref: '#/components/responses/InvalidRequestError' '404': $ref: '#/components/responses/NotFoundError' '409': $ref: '#/components/responses/ActionNotAllowedError' '503': $ref: '#/components/responses/FeatureDisabledError' '500': $ref: '#/components/responses/InternalError' /api/public/signup/sessions/{sessionId}: get: tags: [Public Signup] operationId: getPublicSignupSession summary: Get current signup session status security: [] parameters: - name: sessionId in: path required: true schema: type: string format: uuid responses: '200': description: Signup session snapshot content: application/json: schema: $ref: '#/components/schemas/PublicSignupSessionGetResponse' '400': $ref: '#/components/responses/InvalidRequestError' '404': $ref: '#/components/responses/NotFoundError' '503': $ref: '#/components/responses/FeatureDisabledError' '500': $ref: '#/components/responses/InternalError' /api/public/billing/setup-session: post: tags: [Billing] operationId: createPublicBillingSetupSession summary: Create a Stripe SetupIntent for tenant billing setup description: | Creates or reuses the tenant Stripe customer and returns a SetupIntent client secret. Requires an integration bearer token and an active tenant. requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/BillingSetupSessionRequest' responses: '201': description: Billing setup session created content: application/json: schema: $ref: '#/components/schemas/BillingSetupSessionResponse' '401': $ref: '#/components/responses/AuthError' '403': $ref: '#/components/responses/PrincipalDeniedError' '500': $ref: '#/components/responses/InternalError' /api/auth/token/integration: post: tags: [Auth] operationId: createIntegrationToken summary: Start an integration session (API key to bearer token) description: | Use this endpoint as step 1 in every integration flow. Exchange a valid integration key (`x-api-key`) for a short-lived JWT bearer token, then call tenant endpoints with `Authorization: Bearer <token>`. security: - integrationKeyHeader: [] responses: '200': description: Token issued content: application/json: schema: $ref: '#/components/schemas/IntegrationTokenResponse' examples: success: value: access_token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9... token_type: Bearer expires_in: 3600 default_adapter: catalog-excel '400': $ref: '#/components/responses/MissingApiKeyError' '401': $ref: '#/components/responses/AuthError' '429': $ref: '#/components/responses/RateLimitedError' '500': $ref: '#/components/responses/InternalError' /api/jobs: get: tags: [Jobs] operationId: listJobs summary: Monitor async jobs for the authenticated tenant description: | Use this endpoint to monitor queue activity after upload/screening enqueue calls. Supports filtering by job type and status for dashboards, polling loops, and alerts. parameters: - name: type in: query description: | Optional job type filter. Public integrations should use `catalog_upload` for trade catalog jobs. (Legacy upload type values may still appear in older data but are not part of this public contract.) schema: type: string enum: - ship_upload - sima_validation - catalog_upload - order_upload - carrier_agreement_upload - notification_digest - notification_event - name: status in: query description: Optional status filter. schema: type: string enum: [PENDING, PROCESSING, COMPLETED, FAILED] - name: limit in: query schema: type: integer minimum: 1 maximum: 100 default: 50 - name: offset in: query schema: type: integer minimum: 0 default: 0 responses: '200': description: Job list content: application/json: schema: $ref: '#/components/schemas/JobsListResponse' '400': $ref: '#/components/responses/InvalidRequestError' '401': $ref: '#/components/responses/AuthError' '429': $ref: '#/components/responses/RateLimitedError' '500': $ref: '#/components/responses/InternalError' /api/jobs/{id}: get: tags: [Jobs] operationId: getJobById summary: Get one async job by ID description: | Poll this endpoint until the job reaches a terminal state (`COMPLETED` or `FAILED`). This is the canonical status endpoint for enqueue-based workflows. parameters: - name: id in: path required: true schema: type: string format: uuid responses: '200': description: Job detail content: application/json: schema: $ref: '#/components/schemas/JobResponse' '400': $ref: '#/components/responses/InvalidRequestError' '401': $ref: '#/components/responses/AuthError' '404': $ref: '#/components/responses/NotFoundError' '429': $ref: '#/components/responses/RateLimitedError' '500': $ref: '#/components/responses/InternalError' /api/sima/batch: post: tags: [Trade Screening] operationId: enqueueSimaBatch summary: Queue SIMA screening for catalog SKUs description: | Creates an async SIMA validation job for selected or all SKUs in the tenant catalog. Use this as step 2 in the canonical screening flow. `screeningAuthority` is optional: - omitted or blank: defaults to CA in downstream workers - provided: must normalize to `CA` or `US` parameters: - $ref: '#/components/parameters/IdempotencyKeyHeader' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SimaBatchRequest' examples: allSkus: value: skus: null runPolicy: always screeningAuthority: US responses: '202': description: Job accepted content: application/json: schema: $ref: '#/components/schemas/JobAcceptedResponse' '400': $ref: '#/components/responses/InvalidRequestError' '401': $ref: '#/components/responses/AuthError' '409': $ref: '#/components/responses/ActionNotAllowedError' '429': $ref: '#/components/responses/RateLimitedError' '500': $ref: '#/components/responses/InternalError' /api/sima/results: get: tags: [Trade Screening] operationId: listSimaResults summary: Retrieve SIMA outcomes with workflow filters description: | Returns screened SKU outcomes (`AT_RISK`, `NEEDS_REVIEW`, `CLEARED`) plus workflow state. Use this for flagged queues, analyst review surfaces, and downstream automations. parameters: - name: outcome in: query schema: type: string enum: [AT_RISK, NEEDS_REVIEW, CLEARED] - name: workflow in: query schema: type: string enum: [OPEN, OVERRIDDEN, ACCEPTED, DISMISSED] - name: workflow_not in: query schema: type: string enum: [OPEN, OVERRIDDEN, ACCEPTED, DISMISSED] - name: hs_in_scope in: query schema: type: boolean - name: is_stale in: query schema: type: boolean - name: limit in: query schema: type: integer minimum: 1 maximum: 1000 default: 50 - name: offset in: query schema: type: integer minimum: 0 default: 0 - name: cursor in: query schema: type: string responses: '200': description: SIMA outcomes content: application/json: schema: $ref: '#/components/schemas/SimaResultsResponse' '400': $ref: '#/components/responses/InvalidRequestError' '401': $ref: '#/components/responses/AuthError' '429': $ref: '#/components/responses/RateLimitedError' '500': $ref: '#/components/responses/InternalError' /api/sima/summary: get: tags: [Trade Screening] operationId: getSimaSummary summary: Get SIMA KPI summary counts description: | Returns aggregate KPI counts for SIMA outcomes and workflow buckets. Use this endpoint to power dashboard cards and high-level risk rollups. parameters: - name: outcome in: query schema: type: string enum: [AT_RISK, NEEDS_REVIEW, CLEARED] - name: workflow in: query schema: type: string enum: [OPEN, OVERRIDDEN, ACCEPTED, DISMISSED] - name: workflow_not in: query schema: type: string enum: [OPEN, OVERRIDDEN, ACCEPTED, DISMISSED] responses: '200': description: SIMA summary content: application/json: schema: $ref: '#/components/schemas/SimaSummaryResponse' '400': $ref: '#/components/responses/InvalidRequestError' '401': $ref: '#/components/responses/AuthError' '429': $ref: '#/components/responses/RateLimitedError' '500': $ref: '#/components/responses/InternalError' /api/sima/results/{sku}/evidence: get: tags: [Trade Screening] operationId: getSimaEvidenceBySku summary: Explain one SKU screening decision description: | Returns detailed evidence for a SKU outcome, including classification context, matched signals, and workflow/audit trail data used for analyst review. parameters: - name: sku in: path required: true schema: type: string responses: '200': description: Evidence payload content: application/json: schema: $ref: '#/components/schemas/SimaEvidenceResponse' '401': $ref: '#/components/responses/AuthError' '404': $ref: '#/components/responses/NotFoundError' '429': $ref: '#/components/responses/RateLimitedError' '500': $ref: '#/components/responses/InternalError' /api/sima/report: get: tags: [Trade Screening] operationId: exportSimaReport summary: Export SIMA report data (JSON or CSV) description: | Export SIMA outcomes for BI tools, spreadsheets, and downstream reconciliation. Returns JSON by default or CSV when `format=csv`. parameters: - name: format in: query schema: type: string enum: [json, csv] default: json - name: filter in: query schema: type: string enum: [flagged, covered] - name: status in: query schema: type: string responses: '200': description: Report export content: application/json: schema: $ref: '#/components/schemas/SimaReportJsonResponse' text/csv: schema: type: string '401': $ref: '#/components/responses/AuthError' '429': $ref: '#/components/responses/RateLimitedError' '500': $ref: '#/components/responses/InternalError' /api/upload: post: tags: [Uploads] operationId: enqueueTradeUpload summary: Upload a trade catalog file for async processing description: | Enqueues a trade catalog file and returns a job ID for async processing. Use the returned `jobId` with `/api/jobs/{id}` until terminal status. parameters: - $ref: '#/components/parameters/IdempotencyKeyHeader' requestBody: required: true content: multipart/form-data: schema: $ref: '#/components/schemas/TradeUploadRequest' responses: '202': description: Upload accepted content: application/json: schema: $ref: '#/components/schemas/UploadAcceptedResponse' '400': $ref: '#/components/responses/InvalidRequestError' '401': $ref: '#/components/responses/AuthError' '409': $ref: '#/components/responses/ActionNotAllowedError' '429': $ref: '#/components/responses/RateLimitedError' '413': $ref: '#/components/responses/FileTooLargeError' '415': $ref: '#/components/responses/InvalidFileFormatError' '500': $ref: '#/components/responses/InternalError' /api/catalog/upload: post: tags: [Uploads] operationId: enqueueCatalogUpload summary: Upload a product catalog for screening pipelines description: | Enqueues product catalog ingestion and normalization. Use this when your integration starts from SKU catalog files before SIMA screening. parameters: - $ref: '#/components/parameters/IdempotencyKeyHeader' requestBody: required: true content: multipart/form-data: schema: $ref: '#/components/schemas/CatalogUploadRequest' responses: '202': description: Upload accepted content: application/json: schema: $ref: '#/components/schemas/CatalogUploadAcceptedResponse' '400': $ref: '#/components/responses/InvalidRequestError' '401': $ref: '#/components/responses/AuthError' '409': $ref: '#/components/responses/ActionNotAllowedError' '429': $ref: '#/components/responses/RateLimitedError' '413': $ref: '#/components/responses/FileTooLargeError' '415': $ref: '#/components/responses/InvalidFileFormatError' '500': $ref: '#/components/responses/InternalError' /api/ship/upload: post: tags: [Uploads] operationId: enqueueShipUpload summary: Upload shipment/invoice CSV for freight audit description: | Enqueues shipment and invoice data for async freight-audit processing. Optional `adapter_id` is used for integration-key adapter allowlist enforcement. requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary adapter_id: type: string description: Optional adapter identifier for integration-key adapter allowlist checks. responses: '202': description: Upload accepted content: application/json: schema: $ref: '#/components/schemas/ShipUploadAcceptedResponse' '400': $ref: '#/components/responses/InvalidRequestError' '401': $ref: '#/components/responses/AuthError' '403': $ref: '#/components/responses/AdapterNotAllowedError' '409': $ref: '#/components/responses/DuplicateUploadError' '429': $ref: '#/components/responses/RateLimitedError' '413': $ref: '#/components/responses/FileTooLargeError' '415': $ref: '#/components/responses/InvalidFileFormatError' '500': $ref: '#/components/responses/InternalError' /api/orders/upload: post: tags: [Uploads] operationId: enqueueOrdersUpload summary: Upload order CSV for order-side enrichment/reconciliation description: | Enqueues order ingestion used by downstream shipment/order workflows. `ingestMode` controls patch vs full-snapshot behavior. requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary ingestMode: type: string enum: [PATCH, SNAPSHOT] responses: '202': description: Upload accepted content: application/json: schema: $ref: '#/components/schemas/OrderUploadAcceptedResponse' '400': $ref: '#/components/responses/InvalidRequestError' '401': $ref: '#/components/responses/AuthError' '409': $ref: '#/components/responses/DuplicateUploadError' '429': $ref: '#/components/responses/RateLimitedError' '413': $ref: '#/components/responses/FileTooLargeError' '415': $ref: '#/components/responses/InvalidFileFormatError' '500': $ref: '#/components/responses/InternalError' /api/carrier/agreements/upload: post: tags: [Uploads] operationId: enqueueCarrierAgreementUpload summary: Upload carrier agreement CSV for contract-rate checks description: | Enqueues carrier agreement ingestion used to validate billed rates against contract terms. Requires `ship:upload` scope for integration principals. x-rgl8r-required-scopes: ['ship:upload'] requestBody: required: true content: multipart/form-data: schema: type: object required: [file] properties: file: type: string format: binary responses: '202': description: Upload accepted content: application/json: schema: $ref: '#/components/schemas/ShipUploadAcceptedResponse' '400': $ref: '#/components/responses/InvalidRequestError' '401': $ref: '#/components/responses/AuthError' '403': $ref: '#/components/responses/ScopeDeniedError' '409': $ref: '#/components/responses/DuplicateUploadError' '429': $ref: '#/components/responses/RateLimitedError' '413': $ref: '#/components/responses/FileTooLargeError' '415': $ref: '#/components/responses/InvalidFileFormatError' '500': $ref: '#/components/responses/InternalError' components: securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT integrationKeyHeader: type: apiKey in: header name: x-api-key parameters: IdempotencyKeyHeader: name: Idempotency-Key in: header required: false description: | Optional idempotency key for retry-safe enqueue semantics. Scoped by tenant + endpoint + key. schema: type: string minLength: 1 maxLength: 200 responses: MissingApiKeyError: description: Missing integration key header content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' example: code: MISSING_API_KEY message: Integration key required in x-api-key header InvalidRequestError: description: Request validation failed content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' example: code: INVALID_REQUEST message: Invalid request payload AuthError: description: Authentication failed (invalid/revoked/expired token or key) content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' examples: invalidToken: value: code: INVALID_TOKEN message: Invalid or expired token revokedKey: value: code: REVOKED_API_KEY message: This integration key has been revoked ScopeDeniedError: description: Principal authenticated but missing required scope(s) content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' example: code: SCOPE_DENIED message: Insufficient permissions details: required: ['ship:upload'] provided: ['jobs:read'] PrincipalDeniedError: description: Principal type is not allowed for this endpoint content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' example: code: PRINCIPAL_DENIED message: This endpoint requires integration authentication details: required: [integration] actual: clerk ActionNotAllowedError: description: Request conflicts with current resource/action state content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' example: code: ACTION_NOT_ALLOWED message: Idempotency-Key was already used with a different request payload RateLimitedError: description: Rate limit exceeded content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' example: code: RATE_LIMITED message: Rate limit exceeded details: bucket: read limit: 240 windowMs: 60000 retryAfterSeconds: 12 FeatureDisabledError: description: Feature is disabled by runtime flag headers: Retry-After: description: Seconds until retry is recommended schema: type: integer content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' example: code: FEATURE_DISABLED message: Self-serve signup is currently disabled details: retryAfterSeconds: 300 InternalError: description: Unexpected server error content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' example: code: INTERNAL_ERROR message: An unexpected error occurred NotFoundError: description: Requested resource not found content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' example: code: NOT_FOUND message: Resource not found DuplicateUploadError: description: Duplicate file upload rejected content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' example: code: DUPLICATE_UPLOAD message: This file has already been uploaded details: existingJobId: 11111111-1111-1111-1111-111111111111 uploadedAt: '2026-02-24T13:05:00.000Z' FileTooLargeError: description: File exceeds size limit content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' example: code: FILE_TOO_LARGE message: File too large. Maximum size is 50MB. InvalidFileFormatError: description: File type is not accepted content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' example: code: INVALID_FILE_FORMAT message: Only CSV files are allowed AdapterNotAllowedError: description: Integration key adapter allowlist denied upload content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' example: code: ADAPTER_NOT_ALLOWED message: Requested adapter is not allowed for this integration key schemas: ErrorEnvelope: type: object required: [code, message] properties: code: type: string message: type: string details: type: object additionalProperties: true IntegrationTokenResponse: type: object required: [access_token, token_type, expires_in] properties: access_token: type: string token_type: type: string enum: [Bearer] expires_in: type: integer example: 3600 default_adapter: type: string nullable: true PublicSignupSessionCreateRequest: type: object required: [companyName, slug, modules, adminEmail, legalAcceptance] properties: companyName: type: string slug: type: string modules: type: array minItems: 1 items: type: string enum: [ship, trade] adminEmail: type: string format: email adminFirstName: type: string adminLastName: type: string legalAcceptance: type: object required: [termsVersion, privacyVersion, acceptedAt, ip] properties: termsVersion: type: string privacyVersion: type: string acceptedAt: type: string format: date-time ip: type: string userAgent: type: string PublicSignupSessionCreateResponse: type: object required: [sessionId, status, verificationExpiresAt, expiresAt] properties: sessionId: type: string format: uuid status: type: string enum: [PENDING_EMAIL_VERIFICATION] verificationExpiresAt: type: string format: date-time expiresAt: type: string format: date-time PublicSignupSessionStatusResponse: type: object required: [sessionId, status] properties: sessionId: type: string format: uuid status: type: string enum: - PENDING_EMAIL_VERIFICATION - EMAIL_VERIFIED - PROVISIONING - PROVISIONED - REVIEW_REQUIRED - FAILED - EXPIRED PublicSignupProvisionRequest: type: object required: [idempotencyKey] properties: idempotencyKey: type: string integrationKeyTemplate: type: object properties: name: type: string scopes: type: array items: type: string allowedAdapters: type: array items: type: string defaultAdapter: type: string expiresAt: type: string format: date-time PublicSignupProvisionResponse: type: object required: [sessionId, status, tenantSlug, nextSteps] properties: sessionId: type: string format: uuid status: type: string enum: - PROVISIONING - PROVISIONED - REVIEW_REQUIRED - FAILED tenantId: type: string format: uuid nullable: true tenantSlug: type: string clerkOrgId: type: string nullable: true integrationKeyId: type: string format: uuid nullable: true integrationSecret: type: string nullable: true access_token: type: string nullable: true token_type: type: string nullable: true enum: [Bearer] expires_in: type: integer nullable: true nextSteps: type: array items: type: string PublicSignupSessionGetResponse: type: object required: [sessionId, status, companyName, slug, modules, expiresAt, createdAt, updatedAt] properties: sessionId: type: string format: uuid status: type: string companyName: type: string slug: type: string modules: type: array items: type: string reviewReason: type: string nullable: true failureReason: type: string nullable: true tenantId: type: string format: uuid nullable: true expiresAt: type: string format: date-time createdAt: type: string format: date-time updatedAt: type: string format: date-time BillingSetupSessionRequest: type: object properties: billingEmail: type: string format: email description: Optional billing contact email stored on the tenant billing profile. BillingSetupSessionResponse: type: object required: [tenantId, setupIntentId, clientSecret, stripeCustomerId] properties: tenantId: type: string format: uuid setupIntentId: type: string clientSecret: type: string stripeCustomerId: type: string JobAcceptedResponse: type: object required: [jobId, status, message] properties: jobId: type: string format: uuid status: type: string enum: [PENDING, PROCESSING, COMPLETED, FAILED] message: type: string replayed: type: boolean description: True when the request replayed an existing job for the same idempotency key. TradeUploadRequest: type: object required: [file] properties: file: type: string format: binary runPolicy: type: string enum: [always, skip_exact_duplicates] default: always screeningAuthority: type: string enum: [CA, US] CatalogUploadRequest: type: object required: [file] properties: file: type: string format: binary sourceAdapter: type: string enum: [catalog-excel, extended-excel] default: catalog-excel screeningAuthority: type: string enum: [CA, US] UploadAcceptedResponse: type: object required: [jobId, status, message, fileName] properties: jobId: type: string format: uuid status: type: string enum: [PENDING, PROCESSING, COMPLETED, FAILED] message: type: string replayed: type: boolean description: True when the request replayed an existing job for the same idempotency key. fileName: type: string CatalogUploadAcceptedResponse: allOf: - $ref: '#/components/schemas/UploadAcceptedResponse' - type: object required: [sourceAdapter] properties: sourceAdapter: type: string enum: [catalog-excel, extended-excel] ShipUploadAcceptedResponse: type: object required: [jobId, fileName, status] properties: jobId: type: string format: uuid fileName: type: string status: type: string enum: [PENDING] OrderUploadAcceptedResponse: allOf: - $ref: '#/components/schemas/ShipUploadAcceptedResponse' - type: object required: [ingestMode] properties: ingestMode: type: string enum: [PATCH, SNAPSHOT] JobReconciliation: type: object required: [rowsUploaded, rowsSkipped, rowsDeduplicated, skusFound, skusScreened, skusNotApplicable] properties: rowsUploaded: type: integer nullable: true rowsSkipped: type: integer nullable: true rowsDeduplicated: type: integer nullable: true skusFound: type: integer skusScreened: type: integer skusNotApplicable: type: integer JobOutcomeCounts: type: object required: [atRisk, cleared, needsReview, falsePositive] properties: atRisk: type: integer cleared: type: integer needsReview: type: integer falsePositive: type: integer JobSkippedRows: type: object required: [counts] properties: counts: type: object nullable: true additionalProperties: type: integer sample: type: array nullable: true items: type: object additionalProperties: true JobResponse: type: object required: - id - type - status - progress - result - reconciliation - skippedRows - warnings - outcomes - error - createdAt - updatedAt properties: id: type: string format: uuid type: type: string status: type: string enum: [PENDING, PROCESSING, COMPLETED, FAILED] progress: type: integer fileName: type: string result: type: object additionalProperties: true reconciliation: $ref: '#/components/schemas/JobReconciliation' skippedRows: $ref: '#/components/schemas/JobSkippedRows' warnings: type: object nullable: true additionalProperties: type: integer outcomes: $ref: '#/components/schemas/JobOutcomeCounts' error: type: string nullable: true createdAt: type: string format: date-time updatedAt: type: string format: date-time JobsListResponse: type: object required: [jobs, count] properties: jobs: type: array items: $ref: '#/components/schemas/JobResponse' count: type: integer SimaBatchRequest: type: object properties: skus: type: array nullable: true items: type: string runPolicy: type: string enum: [always, skip_exact_duplicates] default: always screeningAuthority: type: string enum: [CA, US] SimaResultItem: type: object required: - id - sku - outcome - status - workflowStatus - hsInScope - currentHs - confidence - analysisDate - isStale - exposureAnnual - missingAttributes properties: id: type: string format: cuid sku: type: string outcome: type: string enum: [AT_RISK, NEEDS_REVIEW, CLEARED] status: type: string enum: [AT_RISK, NEEDS_REVIEW, CLEARED] workflowStatus: type: string nullable: true enum: [OPEN, OVERRIDDEN, ACCEPTED, DISMISSED] reasonCode: type: string nullable: true measureCode: type: string nullable: true hsInScope: type: boolean currentHs: type: string correctedHs: type: string nullable: true countryOfOrigin: type: string nullable: true materialType: type: string nullable: true confidence: type: number evidence: type: object nullable: true additionalProperties: true analysisDate: type: string format: date-time simaConfigVersion: type: string nullable: true needsReviewSince: type: string format: date-time nullable: true isStale: type: boolean exposureAnnual: type: number nullable: true adRate: type: number nullable: true cvdRate: type: number nullable: true combinedRate: type: number nullable: true caseNumber: type: string nullable: true hasRestrictedComponents: type: boolean missingAttributes: type: array items: type: string SimaResultsResponse: type: object required: [outcomes, total, limit, hasMore, cursor] properties: outcomes: type: array items: $ref: '#/components/schemas/SimaResultItem' total: type: integer limit: type: integer offset: type: integer cursor: type: string nullable: true hasMore: type: boolean SimaSummaryResponse: type: object required: [totalSkus, atRisk, needsReview, totalExposure] properties: totalSkus: type: integer atRisk: type: integer needsReview: type: integer totalExposure: type: number SimaEvidenceResponse: type: object required: [result, classification, attributes, measureApplicability, thresholds, exposure, history, auditTrail] properties: result: type: object additionalProperties: true classification: type: object additionalProperties: true attributes: type: object additionalProperties: true measureApplicability: type: object additionalProperties: true thresholds: type: object additionalProperties: true exposure: type: object additionalProperties: true history: type: array items: type: object additionalProperties: true auditTrail: type: array items: type: object additionalProperties: true SimaReportJsonResponse: type: object required: [generatedAt, tenantId, configVersion] properties: generatedAt: type: string format: date-time tenantId: type: string format: uuid configVersion: type: string totalOutcomes: type: integer totalExposures: type: integer outcomes: type: array items: type: object additionalProperties: true exposures: type: array items: type: object additionalProperties: true