{"openapi":"3.1.0","info":{"title":"Metafold REST API","description":"REST API for running geometry processing operations on the web.\n","version":"1.0.0"},"servers":[{"url":"https://api.metafold3d.com","description":"Production environment"},{"url":"https://dev-api.metafold3d.com","description":"Bleeding-edge (unstable) environment"}],"tags":[{"name":"Projects"},{"name":"Assets"},{"name":"Workflows"},{"name":"Jobs"}],"paths":{"/projects":{"get":{"summary":"Get user projects","description":"List projects for authenticated user","operationId":"getProjects","tags":["Projects"],"parameters":[{"name":"sort","in":"query","schema":{"type":"string"},"description":"Sort string. Must be in the form `field:order`.\n`field` may be one of: id, user, name, created, or modified.\n`order` may be one of -1 for descending or 1 for ascending.\nResources are sorted in descending order by id by default.\n","examples":{"nameAsc":{"value":"name:1"},"sortCreatedDesc":{"value":"created:-1"}}},{"name":"q","in":"query","schema":{"type":"string"},"description":"Query string. See [search query syntax](/topic/topic-search-query-syntax) for\ndetails. Supported search fields are: id, user, and name.\n","examples":{"findName":{"value":"name:\"my-project\""}}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/project"}}}}},"400":{"$ref":"#/components/responses/badRequest"},"401":{"$ref":"#/components/responses/unauthorized"}},"security":[{"oauth2":["projects:read"]}]},"post":{"summary":"Create project","description":"Create project with the given data","operationId":"createProject","tags":["Projects"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"access":{"$ref":"#/components/schemas/projectAccess"}},"required":["name"],"example":{"name":"My Project"}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/project"}}}},"400":{"$ref":"#/components/responses/badRequest"},"401":{"$ref":"#/components/responses/unauthorized"}},"security":[{"oauth2":["projects:write"]}]}},"/projects/{projectId}":{"parameters":[{"$ref":"#/components/parameters/projectId"}],"get":{"summary":"Get user project","description":"Get project by ID","operationId":"getProject","tags":["Projects"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/project"}}}},"400":{"$ref":"#/components/responses/badRequest"},"401":{"$ref":"#/components/responses/unauthorized"},"404":{"$ref":"#/components/responses/notFound"}},"security":[{"oauth2":["projects:read"]}]},"patch":{"summary":"Update user project","description":"Update project by ID","operationId":"updateProject","tags":["Projects"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"access":{"$ref":"#/components/schemas/projectAccess"}},"example":{"name":"My Project","access":"public"}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/project"}}}},"400":{"$ref":"#/components/responses/badRequest"},"401":{"$ref":"#/components/responses/unauthorized"},"404":{"$ref":"#/components/responses/notFound"}},"security":[{"oauth2":["projects:write"]}]},"delete":{"summary":"Delete user project","description":"Delete project by ID","operationId":"deleteProject","tags":["Projects"],"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"const":"OK"}}}},"400":{"$ref":"#/components/responses/badRequest"},"401":{"$ref":"#/components/responses/unauthorized"},"404":{"$ref":"#/components/responses/notFound"}},"security":[{"oauth2":["projects:write"]}]}},"/projects/{projectId}/assets":{"parameters":[{"$ref":"#/components/parameters/projectId"}],"get":{"summary":"Get project assets","description":"List assets in project","operationId":"getAssets","tags":["Assets"],"parameters":[{"name":"sort","in":"query","schema":{"type":"string"},"description":"Sort string. Must be in the form `field:order`.\n`field` may be one of: id, filename, size, created, or modified.\n`order` may be one of -1 for descending or 1 for ascending.\nResources are sorted in descending order by id by default.\n","examples":{"filenameAsc":{"value":"filename:1"},"sizeDesc":{"value":"size:-1"}}},{"name":"q","in":"query","schema":{"type":"string"},"description":"Query string. See [search query syntax](/topic/topic-search-query-syntax) for\ndetails. Supported search fields are: id, and filename.\n","examples":{"findFilename":{"value":"filename:\"part.stl\""}}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/asset"}}}}},"400":{"$ref":"#/components/responses/badRequest"},"401":{"$ref":"#/components/responses/unauthorized"}},"security":[{"oauth2":["assets:read"]}]},"post":{"summary":"Upload project asset","description":"Upload asset to project with the given data","operationId":"createAsset","tags":["Assets"],"requestBody":{"required":true,"content":{"multipart/form-data":{}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/asset"}}}},"400":{"$ref":"#/components/responses/badRequest"},"401":{"$ref":"#/components/responses/unauthorized"}},"security":[{"oauth2":["assets:write"]}]}},"/projects/{projectId}/assets/{assetId}":{"parameters":[{"$ref":"#/components/parameters/projectId"},{"$ref":"#/components/parameters/assetId"}],"get":{"summary":"Get project asset","description":"Get project asset by ID","operationId":"getAsset","tags":["Assets"],"parameters":[{"name":"download","in":"query","schema":{"type":"string"},"description":"Boolean. Either “true” or “1” is accepted.\nResponse will include a link URL to download asset from.\n"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/asset"}}}},"400":{"$ref":"#/components/responses/badRequest"},"401":{"$ref":"#/components/responses/unauthorized"},"404":{"$ref":"#/components/responses/notFound"}},"security":[{"oauth2":["assets:read"]}]},"delete":{"summary":"Delete project asset","description":"Delete project asset by ID","operationId":"deleteAsset","tags":["Assets"],"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"const":"OK"}}}},"400":{"$ref":"#/components/responses/badRequest"},"401":{"$ref":"#/components/responses/unauthorized"},"404":{"$ref":"#/components/responses/notFound"}},"security":[{"oauth2":["assets:write"]}]}},"/projects/{projectId}/workflows":{"parameters":[{"$ref":"#/components/parameters/projectId"}],"get":{"summary":"Get project workflows","description":"List workflows in project","operationId":"getWorkflows","tags":["Workflows"],"parameters":[{"name":"sort","in":"query","schema":{"type":"string"},"description":"Sort string. Must be in the form `field:order`.\n`field` may be one of: id, created, started, or finished.\n`order` may be one of -1 for descending or 1 for ascending.\nResources are sorted in descending order by id by default.\n","examples":{"createdDesc":{"value":"created:-1"},"finishedDesc":{"value":"finished:-1"}}},{"name":"q","in":"query","schema":{"type":"string"},"description":"Query string. See [search query syntax](/topic/topic-search-query-syntax) for\ndetails. Supported search fields are: id, and state.\n","examples":{"findSuccess":{"value":"state:\"success\""}}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/workflow"}}}}},"400":{"$ref":"#/components/responses/badRequest"},"401":{"$ref":"#/components/responses/unauthorized"}},"security":[{"oauth2":["workflows:read"]}]},"post":{"summary":"Run project workflow","description":"Dispatch workflow with given definition","operationId":"createWorkflow","tags":["Workflows"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"definition":{"type":"string","description":"YAML-encoded definition"},"assets":{"$ref":"#/components/schemas/workflowInput"},"parameters":{"$ref":"#/components/schemas/workflowInput"}},"required":["definition"],"example":{"definition":"---\njobs:\n  preprocess-mesh:\n    type: mesh/preprocess\n  compute-bvh:\n    type: mesh/compute-bvh\n    needs:\n    - preprocess-mesh\n    assets:\n      mesh: preprocess-mesh\n  sample-mesh:\n    type: implicit/from-mesh\n    needs:\n    - preprocess-mesh\n    - compute-bvh\n    assets:\n      mesh: preprocess-mesh\n      bvh: compute-bvh\n...\n","assets":{"preprocess-mesh.mesh":"part.stl"},"parameters":{"sample-mesh.resolution":"256"}}}}}},"responses":{"202":{"description":"Accepted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/workflow"}}}},"400":{"$ref":"#/components/responses/badRequest"},"401":{"$ref":"#/components/responses/unauthorized"}},"security":[{"oauth2":["workflows:write","jobs:write","definitions:read"]}]}},"/projects/{projectId}/workflows/{workflowId}":{"parameters":[{"$ref":"#/components/parameters/projectId"},{"$ref":"#/components/parameters/workflowId"}],"get":{"summary":"Get project workflow","description":"Get project workflow by ID","operationId":"getWorkflow","tags":["Workflows"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/workflow"}}}},"400":{"$ref":"#/components/responses/badRequest"},"401":{"$ref":"#/components/responses/unauthorized"},"404":{"$ref":"#/components/responses/notFound"}},"security":[{"oauth2":["workflows:read"]}]},"delete":{"summary":"Delete project workflow","description":"Delete project workflow by ID","operationId":"deleteWorkflow","tags":["Workflows"],"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"const":"OK"}}}},"400":{"$ref":"#/components/responses/badRequest"},"401":{"$ref":"#/components/responses/unauthorized"},"404":{"$ref":"#/components/responses/notFound"}},"security":[{"oauth2":["workflows:write"]}]}},"/projects/{projectId}/workflows/{workflowId}/status":{"parameters":[{"$ref":"#/components/parameters/projectId"},{"$ref":"#/components/parameters/workflowId"}],"get":{"summary":"Get project workflow status","description":"Get status of project workflow by ID","operationId":"getWorkflowStatus","tags":["Workflows"],"responses":{"202":{"description":"Accepted","content":{"application/json":{"schema":{"type":"object","properties":{"state":{"$ref":"#/components/schemas/workflowState"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/workflow"}}}},"400":{"$ref":"#/components/responses/badRequest"},"401":{"$ref":"#/components/responses/unauthorized"},"404":{"$ref":"#/components/responses/notFound"}},"security":[{"oauth2":["workflows:read"]}]}},"/projects/{projectId}/workflows/{workflowId}/cancel":{"parameters":[{"$ref":"#/components/parameters/projectId"},{"$ref":"#/components/parameters/workflowId"}],"post":{"summary":"Cancel project workflow","description":"Cancel project workflow by ID","operationId":"cancelWorkflow","tags":["Workflows"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/workflow"}}}},"400":{"$ref":"#/components/responses/badRequest"},"401":{"$ref":"#/components/responses/unauthorized"},"404":{"$ref":"#/components/responses/notFound"}},"security":[{"oauth2":["workflows:write"]}]}},"/projects/{projectId}/jobs":{"parameters":[{"$ref":"#/components/parameters/projectId"}],"get":{"summary":"Get project jobs","description":"List jobs in project","operationId":"getJobs","tags":["Jobs"],"parameters":[{"name":"sort","in":"query","schema":{"type":"string"},"description":"Sort string. Must be in the form `field:order`.\n`field` may be one of: id, name, created, started, or finished.\n`order` may be one of -1 for descending or 1 for ascending.\nResources are sorted in descending order by id by default.\n","examples":{"nameAsc":{"value":"name:1"},"createdDesc":{"value":"created:-1"}}},{"name":"q","in":"query","schema":{"type":"string"},"description":"Query string. See [search query syntax](/topic/topic-search-query-syntax) for\ndetails. Supported search fields are: id, name, type, and state.\n","examples":{"findName":{"value":"name:\"my-job\""},"findSuccess":{"value":"state:\"success\""}}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/job"}}}}},"400":{"$ref":"#/components/responses/badRequest"},"401":{"$ref":"#/components/responses/unauthorized"}},"security":[{"oauth2":["jobs:read"]}]}},"/projects/{projectId}/jobs/{jobId}":{"parameters":[{"$ref":"#/components/parameters/projectId"},{"$ref":"#/components/parameters/jobId"}],"get":{"summary":"Get project job","description":"Get project job by ID","operationId":"getJob","tags":["Jobs"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/job"}}}},"400":{"$ref":"#/components/responses/badRequest"},"401":{"$ref":"#/components/responses/unauthorized"},"404":{"$ref":"#/components/responses/notFound"}},"security":[{"oauth2":["jobs:read"]}]},"delete":{"summary":"Delete project job","description":"Delete project job by ID","operationId":"deleteJob","tags":["Jobs"],"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"const":"OK"}}}},"400":{"$ref":"#/components/responses/badRequest"},"401":{"$ref":"#/components/responses/unauthorized"},"404":{"$ref":"#/components/responses/notFound"}},"security":[{"oauth2":["jobs:write"]}]}},"/projects/{projectId}/jobs/{jobId}/status":{"parameters":[{"$ref":"#/components/parameters/projectId"},{"$ref":"#/components/parameters/jobId"}],"get":{"summary":"Get project job status","description":"Get status of project job by ID","operationId":"getJobStatus","tags":["Jobs"],"responses":{"202":{"description":"Accepted","content":{"application/json":{"schema":{"type":"object","properties":{"state":{"$ref":"#/components/schemas/jobState"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/job"}}}},"400":{"$ref":"#/components/responses/badRequest"},"401":{"$ref":"#/components/responses/unauthorized"},"404":{"$ref":"#/components/responses/notFound"}},"security":[{"oauth2":["jobs:read"]}]}}},"components":{"parameters":{"projectId":{"description":"Project ID","name":"projectId","in":"path","required":true,"schema":{"type":"string"}},"assetId":{"description":"Asset ID","name":"assetId","in":"path","required":true,"schema":{"type":"string"}},"workflowId":{"description":"Workflow ID","name":"workflowId","in":"path","required":true,"schema":{"type":"string"}},"jobId":{"description":"Job ID","name":"jobId","in":"path","required":true,"schema":{"type":"string"}}},"schemas":{"datetime":{"type":"string","description":"ISO 8601 datetime","example":"2006-01-02T22:04:05+00:00"},"errorResponse":{"type":"object","description":"JSON-encoded HTTP error","properties":{"code":{"type":"integer","description":"HTTP response code"},"name":{"type":"string","description":"Status text corresponding to the HTTP response code"},"description":{"type":"string","description":"Detailed error message"}}},"projectAccess":{"type":"string","description":"Access control","enum":["private","public"]},"project":{"type":"object","description":"Project resource","properties":{"id":{"type":"string"},"user":{"type":"string","description":"Owner ID"},"name":{"type":"string"},"access":{"$ref":"#/components/schemas/projectAccess"},"created":{"$ref":"#/components/schemas/datetime"},"modified":{"$ref":"#/components/schemas/datetime"}},"required":["id","user","name","created","modified"],"example":{"id":"123","user":"auth0|668d4279b22e4ed36b598305","name":"my-project","access":"private","created":"2006-01-02T22:04:05+00:00","modified":"2006-01-02T22:04:05+00:00"}},"asset":{"type":"object","description":"Asset resource","properties":{"id":{"type":"string"},"filename":{"type":"string","example":"part.stl"},"size":{"type":"integer","minimum":0,"description":"Size of file in bytes"},"checksum":{"type":"string","description":"SHA-256 checksum of file contents"},"created":{"$ref":"#/components/schemas/datetime"},"modified":{"$ref":"#/components/schemas/datetime"},"project_id":{"type":"string","description":"Project ID"},"job_id":{"type":"string","nullable":true,"description":"Job ID that created this asset, if any"},"link":{"type":"string","description":"Download URL"}},"required":["id","filename","size","checksum","created","modified","project_id","job_id"],"example":{"id":"123","filename":"part.stl","size":262144,"checksum":"sha256:2d063a84b13e5b23730a509cbb6ba42534acde451249a0b7409172a4f8814ef0","created":"2006-01-02T22:04:05+00:00","modified":"2006-01-02T22:04:05+00:00","project_id":"123","job_id":null}},"workflowState":{"type":"string","enum":["pending","started","success","failure","canceled"],"description":"Current workflow state"},"workflow":{"type":"object","description":"Workflow resource","properties":{"id":{"type":"string"},"jobs":{"type":"array","items":{"type":"string"},"description":"Job IDs"},"state":{"$ref":"#/components/schemas/workflowState"},"created":{"$ref":"#/components/schemas/datetime"},"started":{"$ref":"#/components/schemas/datetime","nullable":true},"finished":{"$ref":"#/components/schemas/datetime","nullable":true},"definition":{"type":"string","description":"Raw definition string"},"project_id":{"type":"string","description":"Project ID"},"link":{"type":"string","description":"Status query URL"}},"required":["id","jobs","state","created","started","finished","definition","project_id"],"example":{"id":"123","jobs":["1","2","3"],"state":"success","created":"2006-01-02T22:04:05+00:00","started":"2006-01-02T22:04:10+00:00","finished":"2006-01-02T22:04:40+00:00","definition":"---\njobs:\n  preprocess-mesh:\n    type: mesh/preprocess\n  compute-bvh:\n    type: mesh/compute-bvh\n    needs:\n    - preprocess-mesh\n    assets:\n      mesh: preprocess-mesh\n  sample-mesh:\n    type: implicit/from-mesh\n    needs:\n    - preprocess-mesh\n    - compute-bvh\n    assets:\n      mesh: preprocess-mesh\n      bvh: compute-bvh\n...\n","project_id":"123"}},"workflowInput":{"type":"object","description":"Input asset or parameter assignments.\nAssignments should be in the form `job.input`,\nwith a `.` dot separating the job name and asset/parameter name.\n","patternProperties":{"^[a-zA-Z0-9-_]+\\.[a-zA-Z0-9-_]+$":{"type":"string","description":"Asset filename or parameter value."}}},"jobState":{"type":"string","description":"Current job state","enum":["pending","started","success","failure","canceled"]},"jobIO":{"type":"object","description":"Job assets and parameters","properties":{"assets":{"type":"object","nullable":true,"description":"Asset mapping","patternProperties":{".":{"$ref":"#/components/schemas/asset"}}},"params":{"type":"object","nullable":true,"description":"Parameter mapping","patternProperties":{".":{"type":"string","description":"Parameter value serialized to string"}}}},"required":["params"]},"job":{"type":"object","description":"Job resource","properties":{"id":{"type":"string"},"name":{"type":"string","nullable":true},"type":{"type":"string","description":"Type name"},"state":{"$ref":"#/components/schemas/jobState"},"created":{"$ref":"#/components/schemas/datetime"},"started":{"$ref":"#/components/schemas/datetime","nullable":true},"finished":{"$ref":"#/components/schemas/datetime","nullable":true},"error":{"type":"string","nullable":true,"description":"Error message for failed jobs"},"inputs":{"$ref":"#/components/schemas/jobIO","description":"Input assets and parameters"},"outputs":{"$ref":"#/components/schemas/jobIO","description":"Output assets and parameters"},"needs":{"type":"array","items":{"type":"string"},"description":"IDs of upstream dependencies"},"project_id":{"type":"string","description":"Project ID"},"workflow_id":{"type":"string","nullable":true,"description":"Workflow ID, if part of a workflow"}},"required":["id","name","type","state","created","started","finished","error","inputs","outputs","needs","project_id","workflow_id"],"example":{"id":"123","name":"sample-mesh","type":"implicit/from-mesh","state":"success","created":"2006-01-02T22:04:05+00:00","started":"2006-01-02T22:04:10+00:00","finished":"2006-01-02T22:04:40+00:00","inputs":{"assets":{"mesh":{"id":"1","filename":"part.stl","size":262144,"checksum":"sha256:2d063a84b13e5b23730a509cbb6ba42534acde451249a0b7409172a4f8814ef0","created":"2006-01-02T22:04:05+00:00","modified":"2006-01-02T22:04:05+00:00"}},"params":{"resolution":"256"}},"outputs":{"assets":{"volume":{"id":"2","filename":"18ac5faec0625a35.bin","size":262144,"checksum":"sha256:d8a0c9a50db61d021c311ef1a57e4531a75f30a3bea44d1db20d82d12d1bb2df","created":"2006-01-02T22:04:05+00:00","modified":"2006-01-02T22:04:05+00:00"}},"params":{"patch":"{\"size\": [2.0, 2.0, 2.0], \"offset\": [-1.0, -1.0, -1.0], \"resolution\": [256, 256, 256]}\n","vertex_count":"3000","face_count":"1000","bounds":"{\"min\": [-1.0, -1.0, -1.0], \"max\": [1.0, 1.0, 1.0]}\n"}},"needs":["1","2"],"project_id":"123","workflow_id":"123"}}},"responses":{"badRequest":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/errorResponse","example":{"code":400,"name":"Bad Request","description":"Expected parameter \"foo\""}}}}},"unauthorized":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/errorResponse","example":{"code":401,"name":"Unauthorzed","description":"Token has expired"}}}}},"notFound":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/errorResponse","example":{"code":404,"name":"Not Found","description":"Resource does not exist"}}}}}},"securitySchemes":{"oauth2":{"type":"oauth2","description":"OAuth 2.0 access token","flows":{"clientCredentials":{"tokenUrl":"https://metafold3d.us.auth0.com/oauth/token","scopes":{"projects:read":"Read user projects","projects:write":"Modify user projects","assets:read":"Read user assets","assets:write":"Modify user assets","workflows:read":"Read user workflows","workflows:write":"Modify user workflows","definitions:read":"Read job definitions this user is authorized to run","jobs:read":"Read user jobs","jobs:write":"Modify user jobs"}}}}}},"x-topics":[{"title":"Getting Started","content":{"$ref":"./docs/start.md"}},{"title":"Authentication","content":{"$ref":"./docs/auth.md"}},{"title":"Workflows","content":{"$ref":"./docs/workflows.md"}},{"title":"Search Query Syntax","content":{"$ref":"./docs/search.md"}}]}