Forge Json API

OpenAPI reference for documents, utilities, and pipelines.

OpenAPI documentation for the public /api/v1 surface.

8 paths12 operationsBearer API key

Authentication

All documented endpoints use Bearer API key authentication.

curl -X GET "$BASE_URL/api/v1/documents?limit=10" \
  -H "Authorization: Bearer fje_your_api_key"

Document size limits

Document upload limits are plan-based. Requests above the current plan limit return 413.

Starter
5 MB
Pro
10 MB
Team
20 MB

Endpoints

Browse each route, example payload, and success response.

/api/v1/documents
getList documents

Lists documents visible to the authenticated API key. Supports folder filtering and cursor pagination.

Example success
{
  "success": true,
  "documents": [
    {
      "id": "jx73rbeegn51rvay2qjjpjfssh83f379",
      "name": "customer-records",
      "title": "customer-records",
      "description": "Imported customer records",
      "tags": [
        "crm",
        "import"
      ],
      "folderId": "k97p0g6c8h9m1n2b3v4x5z6a7s8d9f0q",
      "fileSize": 2048,
      "createdAt": 1774283979968,
      "updatedAt": 1774283982042
    }
  ],
  "nextCursor": "jx78y1btc85h4mkq10ms9kgs4x83f5f7"
}
Responses:200400401403429500
Common 400: INVALID_LIMIT
postCreate a document

Document upload limits are plan-based: Starter 5MB, Pro 10MB, Team 20MB. Requests above the current plan limit return 413. Send either content or contentText, not both. contentText is validated as JSON and stored exactly. Creates the initial document version.

Example request
{
  "name": "customer-records",
  "description": "Imported customer records",
  "tags": [
    "crm",
    "import"
  ],
  "folder": "imports/2026",
  "contentText": "{\n  \"customers\": [\n    { \"id\": 1, \"email\": \"ada@example.com\" }\n  ]\n}\n"
}
Responses:201400401403413429500
Common 400: INVALID_JSON
/api/v1/folders
getList child folders

Lists direct child folders under a parent folder path. Missing parents return an empty folders array. Folder names are opaque and preserve exact casing.

Example success
{
  "success": true,
  "folders": [
    {
      "name": "Uo4bmJUIrX8",
      "path": "makecomp-imports/Uo4bmJUIrX8"
    }
  ]
}
Responses:200401403429500
/api/v1/documents/{id}
getGet document metadata
Example success
{
  "success": true,
  "document": {
    "id": "jx73rbeegn51rvay2qjjpjfssh83f379",
    "name": "customer-records",
    "title": "customer-records",
    "description": "Imported customer records",
    "tags": [
      "crm",
      "import"
    ],
    "folderId": "k97p0g6c8h9m1n2b3v4x5z6a7s8d9f0q",
    "fileSize": 2048,
    "createdAt": 1774283979968,
    "updatedAt": 1774283982042
  }
}
Responses:200401403404429500
putUpdate document metadata
Example request
{
  "name": "customer-records-updated",
  "description": "Reviewed and normalized",
  "tags": [
    "crm",
    "reviewed"
  ],
  "folder": "imports/reviewed"
}
Example success
{
  "success": true,
  "document": {
    "id": "jx73rbeegn51rvay2qjjpjfssh83f379",
    "name": "customer-records-updated",
    "title": "customer-records-updated",
    "description": "Reviewed and normalized",
    "tags": [
      "crm",
      "reviewed"
    ],
    "folderId": "k97p0g6c8h9m1n2b3v4x5z6a7s8d9f0q",
    "fileSize": 2048,
    "createdAt": 1774283979968,
    "updatedAt": 1774284982042
  }
}
Responses:200400401403404429500
Common 400: NO_UPDATES
deleteSoft-delete a document
Example success
{
  "success": true,
  "deleted": true,
  "purgeAt": 1776875982042
}
Responses:200401403404429500
/api/v1/documents/{id}/content
getDownload document content
Responses:200401403404429500
putReplace document content

Document upload limits are plan-based: Starter 5MB, Pro 10MB, Team 20MB. Requests above the current plan limit return 413. Send either content or contentText, not both. By default this creates a new document version. Set createVersion to false to replace the current stored content without creating version history.

Example request
{
  "contentText": "{\n  \"customers\": [\n    { \"id\": 1, \"email\": \"ada@example.com\" }\n  ]\n}\n",
  "createVersion": false
}
Example success
{
  "success": true,
  "fileSize": 2048
}
Responses:200400401403404413429500
Common 400: INVALID_JSON
/api/v1/documents/{id}/purge
postPermanently delete a soft-deleted document
Example success
{
  "success": true,
  "deleted": true,
  "permanent": true
}
Responses:200400401403404429500
/api/v1/utilities/{utilityId}
postRun a utility
Example request
{
  "inputs": {
    "primary": {
      "customer_name": "  Ada Lovelace  "
    }
  },
  "config": {
    "trimWhitespace": true
  }
}
Example success
{
  "success": true,
  "output": {
    "customer_name": "Ada Lovelace"
  },
  "durationMs": 12,
  "creditsUsed": 1
}
Responses:200400401403404408413429500
Common 400: INVALID_JSON
/api/v1/ai/pipeline-draft
postGenerate an AI pipeline draft

Generates a pipeline draft from a natural-language intent and a sample JSON input. Returns both the validated draft (as `steps[]`) and a full pipeline graph (`nodes` + `edges`) ready for import or execution. Requires a bound AI provider credential on the API key (BYO).

Example request
{
  "intent": "Clean each customer record: trim the name, lowercase the email, and drop null fields.",
  "sampleInput": "[{\"name\":\"  Ada  \",\"email\":\"ADA@EXAMPLE.COM\",\"note\":null}]",
  "model": "gpt-4o-mini"
}
Example success
{
  "success": true,
  "draft": {
    "steps": [
      {
        "utilityId": "cleanup.format-values",
        "config": {
          "targets": [
            "name"
          ],
          "operation": "trim"
        }
      },
      {
        "utilityId": "cleanup.format-values",
        "config": {
          "targets": [
            "email"
          ],
          "operation": "lowercase"
        }
      },
      {
        "utilityId": "schema.clean-json",
        "config": {
          "removeNulls": true
        }
      }
    ],
    "explanation": "Trim the name, lowercase the email, then drop fields with null values."
  },
  "pipeline": {
    "nodes": [],
    "edges": []
  },
  "explanation": "Trim the name, lowercase the email, then drop fields with null values.",
  "remaining": 47,
  "nearingLimit": false
}
Responses:200400401403408413429500502503
Common 400: UNKNOWN
/api/v1/pipelines/{pipelineId}/run
postRun a pipeline
Example request
{
  "inputs": {
    "default": {
      "customer_name": "Ada Lovelace"
    }
  },
  "verbose": true
}
Example success
{
  "success": true,
  "output": {
    "greeting": "Hello Ada Lovelace"
  },
  "durationMs": 46,
  "creditsUsed": 1,
  "stepOutputs": {
    "input_1": {
      "customer_name": "Ada Lovelace"
    },
    "format_name": {
      "greeting": "Hello Ada Lovelace"
    }
  }
}
Responses:200400401403404408413429500
Common 400: PIPELINE_NO_OUTPUT

Shared schemas

Common request and response shapes used across the API reference.

ErrorResponse
{
  "type": "object",
  "properties": {
    "success": {
      "type": "boolean",
      "enum": [
        false
      ]
    },
    "error": {
      "type": "string"
    },
    "code": {
      "type": "string"
    }
  },
  "required": [
    "success",
    "error"
  ],
  "additionalProperties": false
}
Document
{
  "type": "object",
  "required": [
    "id",
    "name",
    "title",
    "tags",
    "createdAt",
    "updatedAt"
  ],
  "properties": {
    "id": {
      "type": "string"
    },
    "name": {
      "type": "string"
    },
    "title": {
      "type": "string"
    },
    "description": {
      "type": "string"
    },
    "tags": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "folderId": {
      "type": "string"
    },
    "fileSize": {
      "type": "number"
    },
    "createdAt": {
      "type": "number"
    },
    "updatedAt": {
      "type": "number"
    }
  },
  "additionalProperties": false
}
DocumentListResponse
{
  "type": "object",
  "properties": {
    "success": {
      "type": "boolean",
      "enum": [
        true
      ]
    },
    "documents": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/Document"
      }
    },
    "nextCursor": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ]
    }
  },
  "required": [
    "success",
    "documents",
    "nextCursor"
  ],
  "additionalProperties": false
}
DocumentResponse
{
  "type": "object",
  "properties": {
    "success": {
      "type": "boolean",
      "enum": [
        true
      ]
    },
    "document": {
      "$ref": "#/components/schemas/Document"
    }
  },
  "required": [
    "success",
    "document"
  ],
  "additionalProperties": false
}
Folder
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "description": "Direct child folder name preserved exactly as stored. Treat as opaque text."
    },
    "path": {
      "type": "string",
      "description": "Full folder path, for example `makecomp-imports/Uo4bmJUIrX8`."
    }
  },
  "required": [
    "name",
    "path"
  ],
  "additionalProperties": false
}
FolderListResponse
{
  "type": "object",
  "properties": {
    "success": {
      "type": "boolean",
      "enum": [
        true
      ]
    },
    "folders": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/Folder"
      }
    }
  },
  "required": [
    "success",
    "folders"
  ],
  "additionalProperties": false
}
DocumentCreateRequest
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "description": {
      "type": "string"
    },
    "tags": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "folder": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ]
    },
    "content": {
      "description": "JSON value to store compactly. Mutually exclusive with contentText."
    },
    "contentText": {
      "type": "string",
      "description": "Formatted JSON text to validate with JSON.parse and store exactly. Mutually exclusive with content."
    }
  },
  "required": [
    "name"
  ],
  "additionalProperties": false
}
DocumentUpdateRequest
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "description": {
      "type": "string"
    },
    "tags": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "folder": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ]
    }
  },
  "additionalProperties": false
}
DocumentContentUpdateRequest
{
  "type": "object",
  "properties": {
    "content": {
      "description": "JSON value to store compactly. Mutually exclusive with contentText. For legacy clients, the entire request body may still be the replacement JSON value."
    },
    "contentText": {
      "type": "string",
      "description": "Formatted JSON text to validate with JSON.parse and store exactly. Mutually exclusive with content."
    },
    "createVersion": {
      "type": "boolean",
      "default": true,
      "description": "When false, replace the current stored content without creating a document_versions row. Defaults to true."
    }
  },
  "additionalProperties": false
}
DocumentContentUpdateResponse
{
  "type": "object",
  "properties": {
    "success": {
      "type": "boolean",
      "enum": [
        true
      ]
    },
    "fileSize": {
      "type": "number"
    }
  },
  "required": [
    "success",
    "fileSize"
  ],
  "additionalProperties": false
}
DeleteDocumentResponse
{
  "type": "object",
  "properties": {
    "success": {
      "type": "boolean",
      "enum": [
        true
      ]
    },
    "deleted": {
      "type": "boolean",
      "enum": [
        true
      ]
    },
    "purgeAt": {
      "type": "number"
    }
  },
  "required": [
    "success",
    "deleted",
    "purgeAt"
  ],
  "additionalProperties": false
}
PurgeDocumentResponse
{
  "type": "object",
  "properties": {
    "success": {
      "type": "boolean",
      "enum": [
        true
      ]
    },
    "deleted": {
      "type": "boolean",
      "enum": [
        true
      ]
    },
    "permanent": {
      "type": "boolean",
      "enum": [
        true
      ]
    }
  },
  "required": [
    "success",
    "deleted",
    "permanent"
  ],
  "additionalProperties": false
}
UtilityRunRequest
{
  "type": "object",
  "properties": {
    "inputs": {
      "type": "object",
      "description": "Named utility inputs. inputs.primary is always required. Multi-input utilities such as deep merge also require inputs.secondary.",
      "properties": {
        "primary": {
          "description": "The primary JSON input for the utility."
        },
        "secondary": {
          "description": "Optional secondary JSON input. Required by multi-input utilities such as deep merge."
        }
      },
      "required": [
        "primary"
      ],
      "additionalProperties": true
    },
    "config": {
      "type": "object",
      "additionalProperties": true
    }
  },
  "required": [
    "inputs"
  ],
  "additionalProperties": false
}
UtilityRunResponse
{
  "type": "object",
  "properties": {
    "success": {
      "type": "boolean",
      "enum": [
        true
      ]
    },
    "output": {},
    "durationMs": {
      "type": "number"
    },
    "creditsUsed": {
      "type": "number"
    }
  },
  "required": [
    "success",
    "output",
    "durationMs",
    "creditsUsed"
  ],
  "additionalProperties": false
}
PipelineRunRequest
{
  "type": "object",
  "properties": {
    "inputs": {
      "type": "object",
      "additionalProperties": true
    },
    "verbose": {
      "type": "boolean"
    }
  },
  "additionalProperties": false
}
PipelineRunResponse
{
  "type": "object",
  "properties": {
    "success": {
      "type": "boolean",
      "enum": [
        true
      ]
    },
    "status": {
      "type": "string",
      "enum": [
        "completed",
        "completed_with_warnings",
        "skipped",
        "failed"
      ]
    },
    "output": {},
    "durationMs": {
      "type": "number"
    },
    "creditsUsed": {
      "type": "number"
    },
    "warnings": {
      "type": "array",
      "items": {
        "type": "object",
        "additionalProperties": true
      }
    },
    "stepOutputs": {
      "type": "object",
      "additionalProperties": true
    }
  },
  "required": [
    "success",
    "status",
    "output",
    "durationMs",
    "creditsUsed"
  ],
  "additionalProperties": false
}
AIDraftErrorItem
{
  "type": "object",
  "properties": {
    "code": {
      "type": "string",
      "description": "Machine-readable error code. Callers should branch on this value rather than parsing `message`.",
      "enum": [
        "UNAUTHORIZED",
        "FORBIDDEN",
        "INVALID_JSON",
        "INVALID_MODEL",
        "INVALID_CONFIG",
        "EMPTY_DRAFT",
        "UNKNOWN_UTILITY",
        "SEMANTIC_MISMATCH",
        "STEP_LIMIT_EXCEEDED",
        "INPUT_TOO_LARGE",
        "MODEL_FAILURE",
        "TIMEOUT",
        "RATE_LIMITED",
        "DAILY_QUOTA_EXCEEDED",
        "PLATFORM_AT_CAPACITY",
        "LIMITER_UNAVAILABLE",
        "USER_KEY_BROKEN",
        "AI_DRAFT_BYO_REQUIRED"
      ]
    },
    "message": {
      "type": "string"
    },
    "stepIndex": {
      "type": "number"
    },
    "utilityId": {
      "type": "string"
    }
  },
  "required": [
    "code",
    "message"
  ],
  "additionalProperties": false
}
AIDraftErrorResponse
{
  "type": "object",
  "properties": {
    "success": {
      "type": "boolean",
      "enum": [
        false
      ]
    },
    "errors": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AIDraftErrorItem"
      }
    }
  },
  "required": [
    "success",
    "errors"
  ],
  "additionalProperties": false
}
AIDraftRequest
{
  "type": "object",
  "properties": {
    "intent": {
      "type": "string",
      "description": "Natural-language description of the transformation (for example, \"Convert this CSV-like JSON array to a clean list of user records with trimmed names\")."
    },
    "sampleInput": {
      "type": "string",
      "description": "A sample JSON input as a string. Maximum 200,000 bytes. The draft is shaped around this sample."
    },
    "model": {
      "type": "string",
      "description": "Optional provider-specific model identifier (e.g. `gpt-4o-mini`). When omitted the account default is used."
    }
  },
  "required": [
    "intent",
    "sampleInput"
  ],
  "additionalProperties": false
}
AIDraftStep
{
  "type": "object",
  "properties": {
    "utilityId": {
      "type": "string",
      "description": "Identifier of a utility available in the Store."
    },
    "config": {
      "type": "object",
      "description": "Config object for the utility. Shape is utility-specific.",
      "additionalProperties": true
    }
  },
  "required": [
    "utilityId",
    "config"
  ],
  "additionalProperties": false
}
AIDraftPlan
{
  "type": "object",
  "properties": {
    "steps": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/AIDraftStep"
      }
    },
    "explanation": {
      "type": "string"
    }
  },
  "required": [
    "steps"
  ],
  "additionalProperties": false
}
AIDraftResponse
{
  "type": "object",
  "properties": {
    "success": {
      "type": "boolean",
      "enum": [
        true
      ]
    },
    "draft": {
      "$ref": "#/components/schemas/AIDraftPlan"
    },
    "pipeline": {
      "type": "object",
      "description": "Full pipeline graph (nodes + edges) ready to import via the pipeline builder or run via `POST /api/v1/pipelines/{pipelineId}/run` after saving.",
      "additionalProperties": true
    },
    "explanation": {
      "type": "string"
    },
    "remaining": {
      "type": "number",
      "description": "Daily AI Draft requests remaining for this caller after this call."
    },
    "nearingLimit": {
      "type": "boolean",
      "description": "True when remaining / daily cap drops below 20%."
    }
  },
  "required": [
    "success",
    "draft",
    "pipeline"
  ],
  "additionalProperties": false
}