const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Employment Agreement Extraction',
rubrics: [
{
slot_name: 'party_name',
label: 'Party Name',
data_type: 'text',
validation_rule: 'non empty strings without any numbers',
object_schema: '',
sources: [{source_workflow_id: '<string>'}],
description: '',
extraction_hint: '<string>',
binding_scope: 'plan',
required: true
}
],
description: '',
body_md: ''
})
};
fetch('https://api.factify.com/v1/workflows', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.factify.com/v1/workflows"
payload = {
"name": "Employment Agreement Extraction",
"rubrics": [
{
"slot_name": "party_name",
"label": "Party Name",
"data_type": "text",
"validation_rule": "non empty strings without any numbers",
"object_schema": "",
"sources": [{ "source_workflow_id": "<string>" }],
"description": "",
"extraction_hint": "<string>",
"binding_scope": "plan",
"required": True
}
],
"description": "",
"body_md": ""
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.factify.com/v1/workflows"
payload := strings.NewReader("{\n \"name\": \"Employment Agreement Extraction\",\n \"rubrics\": [\n {\n \"slot_name\": \"party_name\",\n \"label\": \"Party Name\",\n \"data_type\": \"text\",\n \"validation_rule\": \"non empty strings without any numbers\",\n \"object_schema\": \"\",\n \"sources\": [\n {\n \"source_workflow_id\": \"<string>\"\n }\n ],\n \"description\": \"\",\n \"extraction_hint\": \"<string>\",\n \"binding_scope\": \"plan\",\n \"required\": true\n }\n ],\n \"description\": \"\",\n \"body_md\": \"\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.factify.com/v1/workflows")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Employment Agreement Extraction\",\n \"rubrics\": [\n {\n \"slot_name\": \"party_name\",\n \"label\": \"Party Name\",\n \"data_type\": \"text\",\n \"validation_rule\": \"non empty strings without any numbers\",\n \"object_schema\": \"\",\n \"sources\": [\n {\n \"source_workflow_id\": \"<string>\"\n }\n ],\n \"description\": \"\",\n \"extraction_hint\": \"<string>\",\n \"binding_scope\": \"plan\",\n \"required\": true\n }\n ],\n \"description\": \"\",\n \"body_md\": \"\"\n}")
.asString();curl --request POST \
--url https://api.factify.com/v1/workflows \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Employment Agreement Extraction",
"rubrics": [
{
"slot_name": "party_name",
"label": "Party Name",
"data_type": "text",
"validation_rule": "non empty strings without any numbers",
"object_schema": "",
"sources": [
{
"source_workflow_id": "<string>"
}
],
"description": "",
"extraction_hint": "<string>",
"binding_scope": "plan",
"required": true
}
],
"description": "",
"body_md": ""
}
'{
"id": "wfl_01j9z0000000000000000000a0",
"name": "<string>",
"description": "<string>",
"body_md": "<string>",
"rubrics": [
{
"id": "<string>",
"slot_name": "party_name",
"label": "<string>",
"data_type": "text",
"created_at": "2023-11-07T05:31:56Z",
"validation_rule": "<string>",
"object_schema": "<string>",
"sources": [
{
"source_workflow_id": "<string>"
}
],
"description": "<string>",
"extraction_hint": "<string>",
"required": false
}
],
"created_at": "2023-11-07T05:31:56Z",
"active_revision_id": "<string>"
}{
"type": "about:blank",
"title": "Bad Request",
"status": 400,
"detail": "Request body is malformed or missing required fields."
}{
"type": "about:blank",
"title": "Unauthorized",
"status": 401,
"detail": "Missing or invalid authentication credentials."
}{
"type": "about:blank",
"title": "Forbidden",
"status": 403,
"detail": "You do not have permission to perform this action on this resource."
}{
"type": "about:blank",
"title": "Unprocessable Entity",
"status": 422,
"detail": "Request body failed validation.",
"errors": [
{
"location": "body.email",
"message": "expected string to match format 'email'",
"value": "not-an-email"
}
]
}{
"type": "about:blank",
"title": "Too Many Requests",
"status": 429,
"detail": "Rate limit exceeded. Retry after the period indicated by the Retry-After header."
}{
"type": "about:blank",
"title": "Internal Server Error",
"status": 500,
"detail": "An unexpected error occurred. Retry, and contact support if the issue persists."
}Create workflow
const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Employment Agreement Extraction',
rubrics: [
{
slot_name: 'party_name',
label: 'Party Name',
data_type: 'text',
validation_rule: 'non empty strings without any numbers',
object_schema: '',
sources: [{source_workflow_id: '<string>'}],
description: '',
extraction_hint: '<string>',
binding_scope: 'plan',
required: true
}
],
description: '',
body_md: ''
})
};
fetch('https://api.factify.com/v1/workflows', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.factify.com/v1/workflows"
payload = {
"name": "Employment Agreement Extraction",
"rubrics": [
{
"slot_name": "party_name",
"label": "Party Name",
"data_type": "text",
"validation_rule": "non empty strings without any numbers",
"object_schema": "",
"sources": [{ "source_workflow_id": "<string>" }],
"description": "",
"extraction_hint": "<string>",
"binding_scope": "plan",
"required": True
}
],
"description": "",
"body_md": ""
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.factify.com/v1/workflows"
payload := strings.NewReader("{\n \"name\": \"Employment Agreement Extraction\",\n \"rubrics\": [\n {\n \"slot_name\": \"party_name\",\n \"label\": \"Party Name\",\n \"data_type\": \"text\",\n \"validation_rule\": \"non empty strings without any numbers\",\n \"object_schema\": \"\",\n \"sources\": [\n {\n \"source_workflow_id\": \"<string>\"\n }\n ],\n \"description\": \"\",\n \"extraction_hint\": \"<string>\",\n \"binding_scope\": \"plan\",\n \"required\": true\n }\n ],\n \"description\": \"\",\n \"body_md\": \"\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.factify.com/v1/workflows")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Employment Agreement Extraction\",\n \"rubrics\": [\n {\n \"slot_name\": \"party_name\",\n \"label\": \"Party Name\",\n \"data_type\": \"text\",\n \"validation_rule\": \"non empty strings without any numbers\",\n \"object_schema\": \"\",\n \"sources\": [\n {\n \"source_workflow_id\": \"<string>\"\n }\n ],\n \"description\": \"\",\n \"extraction_hint\": \"<string>\",\n \"binding_scope\": \"plan\",\n \"required\": true\n }\n ],\n \"description\": \"\",\n \"body_md\": \"\"\n}")
.asString();curl --request POST \
--url https://api.factify.com/v1/workflows \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Employment Agreement Extraction",
"rubrics": [
{
"slot_name": "party_name",
"label": "Party Name",
"data_type": "text",
"validation_rule": "non empty strings without any numbers",
"object_schema": "",
"sources": [
{
"source_workflow_id": "<string>"
}
],
"description": "",
"extraction_hint": "<string>",
"binding_scope": "plan",
"required": true
}
],
"description": "",
"body_md": ""
}
'{
"id": "wfl_01j9z0000000000000000000a0",
"name": "<string>",
"description": "<string>",
"body_md": "<string>",
"rubrics": [
{
"id": "<string>",
"slot_name": "party_name",
"label": "<string>",
"data_type": "text",
"created_at": "2023-11-07T05:31:56Z",
"validation_rule": "<string>",
"object_schema": "<string>",
"sources": [
{
"source_workflow_id": "<string>"
}
],
"description": "<string>",
"extraction_hint": "<string>",
"required": false
}
],
"created_at": "2023-11-07T05:31:56Z",
"active_revision_id": "<string>"
}{
"type": "about:blank",
"title": "Bad Request",
"status": 400,
"detail": "Request body is malformed or missing required fields."
}{
"type": "about:blank",
"title": "Unauthorized",
"status": 401,
"detail": "Missing or invalid authentication credentials."
}{
"type": "about:blank",
"title": "Forbidden",
"status": 403,
"detail": "You do not have permission to perform this action on this resource."
}{
"type": "about:blank",
"title": "Unprocessable Entity",
"status": 422,
"detail": "Request body failed validation.",
"errors": [
{
"location": "body.email",
"message": "expected string to match format 'email'",
"value": "not-an-email"
}
]
}{
"type": "about:blank",
"title": "Too Many Requests",
"status": 429,
"detail": "Rate limit exceeded. Retry after the period indicated by the Retry-After header."
}{
"type": "about:blank",
"title": "Internal Server Error",
"status": 500,
"detail": "An unexpected error occurred. Retry, and contact support if the issue persists."
}Authorizations
Bearer authentication using a factapi-issued API key
(ffy_<env>_<base32_uuid><base62_random>). Cookie-based
sessions are accepted automatically by user-facing endpoints
but are not surfaced as an OpenAPI auth scheme.
Body
Human-readable workflow name.
"Employment Agreement Extraction"
Claim slot definitions to create with this workflow.
Show child attributes
Show child attributes
Human-readable workflow description.
Markdown template body with {{slot_name}} placeholders.
Response
Workflow created.
Workflow TypeID (wfl_…)
"wfl_01j9z0000000000000000000a0"
Human-readable workflow name.
Human-readable workflow description. Empty string when unset.
Markdown template body. Claim slot placeholders use {{slot_name}} syntax.
Claim slot definitions for this workflow, in creation order.
Show child attributes
Show child attributes
TypeID (wrev_…) of the workflow's currently active revision. Null when no revision is active (draft-only, never activated).