REST API Reference

The Reforge REST API provides server-side CGM-to-SVG conversion, batch job management, and profile detection.

Licence requirement

API access requires an Enterprise licence. All endpoints return 403 Forbidden without it.


Authentication

X-Api-Key: your-api-key

Base URL

https://your-server/api/v1

Endpoints

Health check

GET /api/v1/health — No authentication required.


Convert by file path

POST /api/v1/convert

{
  "filePath": "/mnt/files/input.cgm",
  "outputDirectory": "/mnt/output",
  "companionFilePath": "/mnt/files/input.xcf",
  "settings": { "profile": "auto", "dpi": 96 }
}

Response: { success, outputPath, profile, conversionDurationMs, hasWatermark }


Convert — upload

POST /api/v1/convert/uploadmultipart/form-data

Field Required Description
file Yes CGM file (max 100 MB)
companionFile No XCF or IMF companion
settings No JSON string of conversion settings

Response: Content-Type: image/svg+xml


Batch convert

POST /api/v1/convert/batch

{
  "filePaths": ["/mnt/files/fig-001.cgm", "/mnt/files/fig-002.cgm"],
  "outputDirectory": "/mnt/output",
  "settings": { "profile": "s1000d" },
  "callbackUrl": "https://your-server/webhooks/reforge",
  "callbackSecret": "your-hmac-secret"
}
Field Required Description
filePaths Yes 1–500 absolute server-side paths
outputDirectory No Defaults to directory of first file
maxParallelFiles No 1–16, default 4
errorHandling No SkipFile (default) · TryConvertAnyway · StopBatch
settings No Conversion settings applied to all files
callbackUrl No URL to POST when the job reaches a terminal state
callbackSecret No HMAC-SHA256 secret for webhook signature verification

Response (202 Accepted): { jobId, status, totalFiles, statusUrl }


Job status

GET /api/v1/jobs/{jobId}

{
  "jobId": "3fa85f64-...",
  "status": "PartiallyCompleted",
  "totalFiles": 100,
  "succeededFiles": 80,
  "failedFiles": 20,
  "successRate": 0.80,
  "progressPercent": 100,
  "submittedAt": "2026-03-23T14:00:00Z",
  "completedAt": "2026-03-23T14:22:00Z"
}

Status values: Queued · Running · Completed · PartiallyCompleted · Failed · Cancelled

  • Completed — all files succeeded
  • PartiallyCompleted — at least one file succeeded and at least one failed
  • Failed — every file failed (or an unhandled error aborted the job)

Job results

GET /api/v1/jobs/{jobId}/results — Returns 202 if still running, 200 with results when complete.

Each entry in the results array:

Field Type Description
inputPath string Original input file path
success bool Whether conversion succeeded
outputPath string? Output SVG path (null on failure)
outputSizeBytes long Output SVG byte size (0 on failure)
profile string? Detected or applied CGM profile
durationMs long Conversion time in milliseconds
companionFileUsed bool Whether an XCF/IMF companion was applied
errorCode string? Structured error code (e.g. EngineError, ValidationFailure)
error string? Human-readable error message
warnings array Quality warnings (see below)

Each warning object:

Field Values Description
code string Machine-readable code (e.g. CONVERSION_WARNING)
severity "Warning" · "Info" Severity level
message string Human-readable description

Cancel job

DELETE /api/v1/jobs/{jobId} — Returns 204 No Content.


Retry failed files

POST /api/v1/jobs/{jobId}/retry

Submits a new job containing only the files that failed in the original job. The original job’s results are not modified — both jobs can be queried independently.

Optional request body (all fields override the original job’s values):

{
  "outputDirectory": "/mnt/output/retry",
  "settings": { "dpi": 150 }
}

Response (202 Accepted):

{
  "originalJobId": "3fa85f64-...",
  "retryJobId": "7cb29a11-...",
  "retryingFiles": 20,
  "statusUrl": "https://your-server/api/v1/jobs/7cb29a11-..."
}

Error responses:

Status Condition
404 Original job not found
409 Conflict Job is still Queued or Running
400 Bad Request Job has no failed files

List profiles

GET /api/v1/profiles — Array of { name, displayName, description }.


Detect profile

POST /api/v1/detect

{ "filePath": "/mnt/files/fig-001.cgm" }

Response: { "detectedProfile": "S1000Dv6" }


Validate

POST /api/v1/validate

{ "filePath": "/mnt/files/fig-001.cgm", "profile": "s1000d" }

Response: { isValid, detectedProfile, issues: [{ severity, code, message }] }


Settings object

Field Default Description
profile "auto" Input profile
dpi 96 Resolution (72–600)
hotspotsEncoding "both" "svgAnchors" "dataAttributes" "both"
textHandling "preserve" "preserve" or "paths"
rasterEncoding "png" "png" "jpeg" "base64" "none"
companionFileMode "auto" "auto" "xcfOnly" "ignore"

Webhook callbacks

When a callbackUrl is supplied on batch submission, the server POSTs the following JSON to that URL when the job reaches a terminal state:

{
  "jobId": "3fa85f64-...",
  "status": "PartiallyCompleted",
  "totalFiles": 100,
  "succeededFiles": 80,
  "failedFiles": 20,
  "completedAt": "2026-03-23T14:22:00Z",
  "resultsUrl": "jobs/3fa85f64-.../results"
}

Signature verification

When callbackSecret is set, each callback request includes:

X-Reforge-Signature: sha256=<hex>

The hex value is HMAC-SHA256(requestBody, callbackSecret). Verify it on your server before processing the payload.

Delivery retries

The server retries failed deliveries up to 3 times with exponential backoff (1 s, 2 s, 4 s). Webhook delivery is best-effort — use GET /jobs/{jobId} to confirm the final state if reliability is critical.