Skip to main content

Types and payloads

This page describes the shapes you work with on the low-level client: the payload you pass to createWorkflow(), the enums that name operations and states, and the status and download responses. The methods themselves are in the Client reference. If you use the file-first builders (file(), files(), merge()), they build the payload for you and you can skip most of this page.

Field casing​

The SDK does not use one casing everywhere. Which one you see depends on where the data came from:

SurfaceCasingExample
Responses from low-level methods (getWorkflowStatus, getWorkflowDownloads, createWorkflow, uploadFile, …)camelCase: properties in TypeScript, getters in PHPstatus.workflowId / $status->getWorkflowId()
The payload you send to createWorkflow, including operation optionssnake_case wire keys (PHP's payload classes take camelCase arguments and write them for you)callback_url, file_id, output_format
SSE event data from streamEvents()snake_case, exactly as the server sent itevent.data.operation_id
Webhook request bodiessnake_case, until you run them through the generated modeldelivery_id, event_type

Enum values are never re-cased. Only field names change: the value of status is in_progress on every surface.

In TypeScript, responses are converted by the generated contract models, which also turn timestamps such as createdAt into Date objects. SSE frames are only JSON.parsed, so their keys stay snake_case, and GislSseEvent types them that way: each event's data is a snake_case wire interface (SseOperationProgressWire, SseOperationCompletedWire and the rest), so event.data.operation_id type-checks and event.data.operationId does not. The camelCase Sse*Data models describe the output of their FromJSON helpers, not the frames streamEvents() yields. In PHP, GislSseEvent::$data is a plain associative array with snake_case keys.

For webhook bodies, see Webhooks.

The workflow payload​

A workflow is a list of jobs. Each job has one source, or several inputs, and an ordered list of operations. Workflows explains the model; the source factories are listed there too.

Wire fieldTypePurpose
jobslist of jobs, at least onethe work
workflow_edgeslist of { from, to } job idsexplicit dependencies; usually inferred from job_output sources
callback_urlstringenables webhooks
callback_eventslist of CallbackEventType valueswhich events are posted to callback_url
notifyNotifyConfig (email channel)per-job completion notifications. Declared ahead of the server: any channel returns feature_not_available (422) today; an empty object is a no-op
export{ type: 'connection', connection_id, path } or { type: 'external_import', external_source_id }write outputs to external storage
deliverymode (individual, bundle, both), bundle_format (zip, tar_gz), bundle_filename, include_metadata, selectionhow outputs are delivered
processingclass_hint (auto, short_form_only, long_form_allowed, long_form_preferred)a hint about the processing class

delivery.selection.type is terminal, all_outputs or explicit; explicit takes refs, a list of { ref, operation? }.

Each job:

Wire fieldPurpose
idoptional label. Needed when another job, an edge or a delivery selection refers to it. The server generates one when omitted and echoes it back as ref.
sourcesingle input: an upload, job_output, external_import or connection source
inputsmultiple inputs: a list of { source, role?, per_input_options? }
operationsordered list of { type, options? }; type is an OperationType value, options uses snake_case keys
delivertrue to deliver this job's output even though another job consumes it; cannot be combined with an explicit delivery selection

Set source or inputs, not both. The SDK does not check this; the server rejects it.

The multi-input operations are merge, archive, image_watermark, video_watermark, audio_overlay, audio_to_video and custom_luma. An inputs[].source cannot be an upload: an uploaded file enters through a job whose only operation is passthrough, which you then reference with a job_output source. A multi-input job has exactly one operation, of one of those types. role is base, overlay or transition_mask.

The payload types are plain objects with wire (snake_case) keys: WorkflowCreatePayload, JobDefinitionPayload, JobInputV2Payload, OperationDef, WorkflowSourcePayload (and MultiInputSourcePayload, the same union without upload), ExternalDestinationPayload, DeliveryPayload and WorkflowProcessingPayload. All are exported from @giveitsmaller/sdk.

import {
CallbackEventType,
JobInputV2RoleEnum,
OperationType,
jobOutputSource,
uploadSource,
type WorkflowCreatePayload,
} from '@giveitsmaller/sdk';

const payload: WorkflowCreatePayload = {
jobs: [
{ id: 'base_src', source: uploadSource(base.fileId), operations: [{ type: OperationType.passthrough }] },
{ id: 'logo_src', source: uploadSource(logo.fileId), operations: [{ type: OperationType.passthrough }] },
{
id: 'watermarked',
inputs: [
{ source: jobOutputSource('base_src'), role: JobInputV2RoleEnum.base },
{ source: jobOutputSource('logo_src'), role: JobInputV2RoleEnum.overlay },
],
operations: [{ type: OperationType.image_watermark, options: { anchor: 'bottom_right' } }],
},
],
callback_url: 'https://example.com/hooks/gisl',
callback_events: [CallbackEventType.workflow_completed],
};
const created = await client.createWorkflow(payload);

WorkflowCreatePayload also declares optional top-level source and operations (a flat single-job form). The server does not accept that form; always send jobs.

The options each operation takes are on the Operations pages.

Enums​

In TypeScript every enum below is a const object with lowercase members, exported from @giveitsmaller/sdk (OperationType.compress). In PHP it is a class of string constants in Gisl\Generated\OpenApi\Model (OperationType::COMPRESS). Both hold the same string values, and response fields carry the plain string.

EnumValuesWhere it appears
OperationTypecompress, thumbnail, thumbnail_image, thumbnail_video, thumbnail_document, thumbnail_office, image_watermark, text_watermark, render_variants, merge, archive, convert, custom_luma, audio_overlay, audio_watermark, audio_to_video, video_watermark, video_text_watermark, split, transform, passthroughoperations[].type; type on each operation in a status response
WorkflowStatuspending, in_progress, completed, failed, partially_failed, paused_insufficient_credits, cancelled, expiredstatus on status and create responses
JobStatuspending, waiting, blocked_insufficient_credits, in_progress, completed, failedjobs[].status
OperationStatuspending, in_progress, completed, failed, retriedjobs[].operations[].status
CallbackEventTypeworkflow.completed, workflow.failed, workflow.partially_failed, operation.completedcallback_events on the payload
SseEventTypeoperation.progress, operation.completed, operation.failed, job.completed, job.failed, workflow.completed, workflow.failed, workflow.partially_failedthe event tag of a streamed event
JobInputV2RoleEnum (TS) / JobInputV2::ROLE_* (PHP)base, overlay, transition_maskinputs[].role

A value being in OperationType does not mean it is available to you: several are planned and return feature_not_available (422). Ask the server with getSchema() or capabilities(); see the Client reference. The file-first thumbnail() verbs send thumbnail.

For the dotted enum values the TypeScript member names use underscores (CallbackEventType.workflow_completed is 'workflow.completed'). Treat an unknown value as possible: new values can be added, and the PHP SDK passes an unrecognised status string through rather than failing.

Status and download responses​

getWorkflowStatus() and waitForWorkflow() return a WorkflowStatusResponse; getWorkflowDownloads() returns a WorkflowDownloadResponse. The paths below are TypeScript properties; in PHP each segment is a getter (jobs[].operations[].result.downloadUrl is $op->getResult()?->getDownloadUrl() inside loops over getJobs() and getOperations()).

WorkflowStatusResponse

PathNotes
workflowId, statusstatus is a WorkflowStatus value
createdAt, updatedAt, completedAt?Date in TypeScript, \DateTime in PHP
jobs[].refthe id you gave the job, or the one the server generated
jobs[].jobId, jobs[].status, jobs[].dependsOndependsOn lists upstream job refs
jobs[].operations[].id, .type, .status, .progress?progress is 0 to 100, present once the operation is in_progress or completed
jobs[].operations[].result?.downloadUrl, .sizeBytes, .mimeType?the operation's output; downloadUrl is pre-signed
jobs[].operations[].result?.metrics?e.g. compressionRatio, durationMs
jobs[].operations[].errorCode?, .errorMessage?present when the operation failed
pausedDetail?present only when status is paused_insufficient_credits

WorkflowDownloadResponse

PathNotes
downloads[].ref, downloads[].jobIdone entry per job
downloads[].files[].operation, .operationIdwhich operation produced the file
downloads[].files[].filename, .sizeBytes, .downloadUrldownloadUrl is pre-signed
bundle?one archive of every deliverable; present only once a bundle requested with delivery.mode bundle or both is ready
retentionExpiresAt?when the outputs are deleted, if the server reports it

createWorkflow() returns a WorkflowCreateResponse: workflowId, status, createdAt, jobs, anonymous, deliveryPlan, processingPlan and warnings, plus webhookSecret, present only when you set callback_url. The response to the create call is the only place the secret appears; store it then. It may also carry cap, a read capability for workflows created without an account (first-party only): keep it, because reads of such a workflow need it ({ capability } in TS) and it is not returned again. Decide whether a workflow is anonymous from anonymous, never from whether cap is present.

See also​