MOI Atomic Pipeline API¶
Overview¶
The MOI Atomic Pipeline API is an asynchronous file-processing pipeline that supports parsing, analysis, and other operations on uploaded files. It is asynchronous: submitting a job returns a job_id that you use later to query results.
API list¶
This document covers the following endpoints:
API |
Method |
Endpoint |
Purpose |
|---|---|---|---|
Submit a file-processing job |
POST |
|
Submit files for processing — supports remote URLs, local uploads, or a mix of both |
Get job status |
GET |
|
Query a submitted job’s status and per-file detail |
Download job results |
GET |
|
Download the processed result archive (ZIP) |
Submit a File-Processing Job¶
Basics¶
Endpoint:
https://freetier-01.cn-hangzhou.cluster.matrixonecloud.cn/v1/genai/pipelineMethod:
POSTRequest format:
application/json— for remote file URLsmultipart/form-data— for local file uploads
Response format:
application/json
Submission modes¶
The endpoint supports three flexible submission modes:
Mode 1: public file URLs
Use
application/jsonPass URLs in the
file_urlsparameterFor files already accessible on the public network
Mode 2: local file uploads
Use
multipart/form-dataUpload local files as form parts
Send both
payloadandfilesfieldsFor files on your local disk
Mode 3: hybrid
Mix local files and remote URLs in a single request
Use
multipart/form-dataIn
payload, set bothfile_urls(remote) andfile_names(local)Upload local file content as
filesparts alongsideThe API processes everything (remote + local) in one job and returns a single
job_id
Headers¶
Name |
Type |
Required |
Description |
|---|---|---|---|
Content-Type |
String |
depends |
Remote URL mode: |
moi-key |
String |
yes |
API key for authentication |
Examples:
Remote URL mode:
Content-Type: application/json
moi-key: YOUR-MOI-KEY
Local upload mode:
moi-key: YOUR-MOI-KEY
Note: when using -F, curl sets Content-Type: multipart/form-data for you.
Request parameters¶
Mode 1: remote file URLs
Send a JSON body directly:
Name |
Type |
Required |
Description |
|---|---|---|---|
file_urls |
Array[String] |
yes |
URL list of files to process; HTTP/HTTPS supported |
file_names |
Array[String] |
no |
Keep as empty array |
meta |
Array |
no |
Metadata for extra processing parameters or identifiers |
steps |
Array[Object] |
yes |
Processing-step configuration; defines the operations applied to the files |
steps[].node |
String |
yes |
Processing-node name, e.g. |
steps[].parameters |
Object |
yes |
Per-node configuration; pass |
Mode 2: local file uploads
Use multipart/form-data with these fields:
Name |
Type |
Required |
Description |
|---|---|---|---|
payload |
String |
yes |
JSON string with the configuration |
payload.file_names |
Array[String] |
yes |
Names of the uploaded files; must match the actual upload field names |
payload.meta |
Array |
no |
Metadata |
payload.steps |
Array[Object] |
yes |
Processing-step configuration |
files |
File |
yes |
Actual file content; multiple files are supported |
Notes:
Pick one of the modes
The
stepsarray defines the pipeline; steps run in orderFor local uploads, names in
file_namesmust match the names used in thefilespartsNodes have ordering constraints — they must appear in the correct order
Processing nodes¶
Available nodes:
Node |
Purpose |
Input |
Output |
|---|---|---|---|
ParseNode |
Parsing |
Raw file |
Structured data (text, tables, images) |
ChunkNode |
Chunking |
Output of ParseNode |
Text chunks |
EmbedNode |
Embedding |
Output of ChunkNode |
Vector embeddings |
ExtractNode |
Extraction |
Raw file or another node’s output |
Targeted extraction |
Allowed combinations (must follow this order):
1. Parse only
"steps": [
{"node": "ParseNode", "parameters": {}}
]
Use case: parse a file to extract text, tables, and images.
2. Parse + chunk
"steps": [
{"node": "ParseNode", "parameters": {}},
{"node": "ChunkNode", "parameters": {}}
]
Use case: parse a file then split the content into chunks for downstream processing.
3. Parse + chunk + embed
"steps": [
{"node": "ParseNode", "parameters": {}},
{"node": "ChunkNode", "parameters": {}},
{"node": "EmbedNode", "parameters": {}}
]
Use case: full document-vectorization pipeline, suitable for semantic search.
4. Parse + chunk + embed + extract
"steps": [
{"node": "ParseNode", "parameters": {}},
{"node": "ChunkNode", "parameters": {}},
{"node": "EmbedNode", "parameters": {}},
{"node": "ExtractNode", "parameters": {}}
]
Use case: parse, vectorize, and pull out targeted information — full-fat document processing.
5. Extract only
"steps": [
{"node": "ExtractNode", "parameters": {}}
]
Use case: pull specific information directly out of a file without going through parsing.
Per-node parameters:
Each node accepts a parameters object to customize its behavior:
{
"node": "NodeName",
"parameters": {
// Node-specific parameters (optional)
// For defaults, pass an empty object {}
}
}
Notes:
If you do not need custom behavior, pass
{}Specific parameter sets vary per node — consult the API provider for details
Different nodes accept different parameter keys
Request examples¶
Example 1: remote file URLs
curl -X POST "https://freetier-01.cn-hangzhou.cluster.matrixonecloud.cn/v1/genai/pipeline" \
-H "Content-Type: application/json" \
-H "moi-key: YOUR-MOI-KEY" \
-d '{
"file_urls": [
"http://www.pdf995.com/samples/pdf.pdf",
"https://example.com/document.pdf"
],
"file_names": [],
"meta": [],
"steps": [
{
"node": "ParseNode",
"parameters": {}
}
]
}'
Notes:
-H "Content-Type: application/json"declares JSON mode-dcarries the JSON bodyfile_urlsmay contain multiple URLsfile_namesis an empty arrayThe API processes all files and returns a single
job_id
Successful response:
{
"code": "OK",
"msg": "OK",
"data": {
"job_id": "b55093a7-ff3c-42ca-a4fe-c4e72074e046"
},
"request_id": "969935d0-363e-4451-a5e3-f71f1d20101e"
}
Example 2: upload local files
curl -X POST "https://freetier-01.cn-hangzhou.cluster.matrixonecloud.cn/v1/genai/pipeline" \
-H "moi-key: YOUR-MOI-KEY" \
-F "files=@/path/to/doc1.pdf" \
-F "files=@/path/to/doc2.pdf" \
-F 'payload={"file_names": ["doc1.pdf", "doc2.pdf"], "steps": [{"node": "ParseNode", "parameters": {}}]}'
Notes:
-Fselects multipart/form-data (no Content-Type header needed)Repeat
-F "files=@<path>"for each filefiles=@<path>reads the file from disk; the@prefix is requiredAll file fields use the same name
filespayloadis a JSON string with the configurationThe order of
file_namesshould match the upload orderNote:
filesparts go beforepayload
Successful response:
{
"code": "OK",
"msg": "OK",
"data": {
"job_id": "cd072050-ce02-406b-8f28-595f2c86eaaa"
},
"request_id": "b6528fde-ebc3-461b-8015-1b7b97ec9c82"
}
Example 3: hybrid (local + remote)
curl -X POST "https://freetier-01.cn-hangzhou.cluster.matrixonecloud.cn/v1/genai/pipeline" \
-H "moi-key: YOUR-MOI-KEY" \
-F "files=@local-report.pdf" \
-F 'payload={"file_urls": ["http://www.pdf995.com/samples/pdf.pdf"], "file_names": ["local-report.pdf"], "steps": [{"node": "ParseNode", "parameters": {}}]}'
Notes:
✅ Local files and remote URLs in a single request
file_urlscarries the remote filesfile_namescarries the local file namesfilesparts upload the local contentThe API processes all files (local + remote) under a single
job_id
Successful response:
{
"code": "OK",
"msg": "OK",
"data": {
"job_id": "322fe48f-698d-4fbb-8851-1a2d9f8031ec"
},
"request_id": "ec636405-82ce-4331-902b-6810a83d17f0"
}
Example 4: parse + chunk
curl -X POST "https://freetier-01.cn-hangzhou.cluster.matrixonecloud.cn/v1/genai/pipeline" \
-H "Content-Type: application/json" \
-H "moi-key: YOUR_API_KEY" \
-d '{
"file_urls": ["http://example.com/document.pdf"],
"file_names": [],
"steps": [
{"node": "ParseNode", "parameters": {}},
{"node": "ChunkNode", "parameters": {}}
]
}'
Notes:
Parse first, then split into chunks
For pipelines that process the document segment by segment
Example 5: full vectorization pipeline
curl -X POST "https://freetier-01.cn-hangzhou.cluster.matrixonecloud.cn/v1/genai/pipeline" \
-H "Content-Type: application/json" \
-H "moi-key: YOUR_API_KEY" \
-d '{
"file_urls": ["http://example.com/document.pdf"],
"file_names": [],
"steps": [
{"node": "ParseNode", "parameters": {}},
{"node": "ChunkNode", "parameters": {}},
{"node": "EmbedNode", "parameters": {}}
]
}'
Notes:
Parse → chunk → embed
Useful for semantic-search indexes and RAG systems
Embeddings are ready for similarity search
Example 6: full pipeline
curl -X POST "https://freetier-01.cn-hangzhou.cluster.matrixonecloud.cn/v1/genai/pipeline" \
-H "Content-Type: application/json" \
-H "moi-key: YOUR_API_KEY" \
-d '{
"file_urls": ["http://example.com/document.pdf"],
"file_names": [],
"steps": [
{"node": "ParseNode", "parameters": {}},
{"node": "ChunkNode", "parameters": {}},
{"node": "EmbedNode", "parameters": {}},
{"node": "ExtractNode", "parameters": {}}
]
}'
Notes:
Parse → chunk → embed → extract
The complete document-processing pipeline
For workloads that need exhaustive document analysis
Example 7: extract only
curl -X POST "https://freetier-01.cn-hangzhou.cluster.matrixonecloud.cn/v1/genai/pipeline" \
-H "Content-Type: application/json" \
-H "moi-key: YOUR_API_KEY" \
-d '{
"file_urls": ["http://example.com/document.pdf"],
"file_names": [],
"steps": [
{"node": "ExtractNode", "parameters": {}}
]
}'
Notes:
Extract specific fields directly from the file
Skips parsing
Best when you only need a small structured payload
Response parameters¶
Successful response:
Name |
Type |
Description |
|---|---|---|
code |
String |
Status code; |
msg |
String |
Status message; |
data |
Object |
Response payload |
data.job_id |
String |
Job ID — use it to query status and results |
request_id |
String |
Unique request id for trace/debug |
Successful response example:
{
"code": "OK",
"msg": "OK",
"data": {
"job_id": "c66f4354-6833-4c75-8d34-d630024e5254"
},
"request_id": "d16e0fc2-50dd-4928-9eac-d55f88e0160c"
}
Error response:
{
"code": "ERROR_CODE",
"msg": "Description of the error",
"data": null,
"request_id": "request id"
}
Get Job Status¶
Basics¶
Endpoint:
https://freetier-01.cn-hangzhou.cluster.matrixonecloud.cn/v1/genai/jobs/{job_id}Method:
GETRequest format: URL path parameter
Response format:
application/json
Headers¶
Name |
Type |
Required |
Description |
|---|---|---|---|
moi-key |
String |
yes |
API key for authentication |
Path parameters¶
Name |
Type |
Required |
Description |
|---|---|---|---|
job_id |
String |
yes |
Job ID returned by the submission API |
Response parameters¶
Successful response:
Name |
Type |
Description |
|---|---|---|
code |
String |
Status code; |
msg |
String |
Status message; |
data |
Object |
Response payload |
data.status |
String |
Overall job status: |
data.files |
Array[Object] |
Per-file processing detail |
data.files[].file_id |
String |
Unique file identifier |
data.files[].file_name |
String |
File name |
data.files[].file_type |
Integer |
File type code |
data.files[].file_status |
String |
Per-file status: |
data.files[].error_message |
String |
Error message; empty string on success |
data.files[].start_time |
String |
When processing started |
data.files[].end_time |
String |
When processing finished |
request_id |
String |
Unique request id |
Request example¶
Example: query job status
curl -X GET "https://freetier-01.cn-hangzhou.cluster.matrixonecloud.cn/v1/genai/jobs/322fe48f-698d-4fbb-8851-1a2d9f8031ec" \
-H "moi-key: YOUR-MOI-KEY"
Notes:
HTTP
GETjob_idis part of the URL pathOnly the
moi-keyheader is required
Response examples¶
Example 1: job completed
{
"code": "OK",
"msg": "OK",
"data": {
"status": "completed",
"files": [
{
"file_id": "019ad8c4-cf7e-75ca-afa1-5bd971ff9ed9",
"file_name": "report.pdf",
"file_type": 2,
"file_status": "completed",
"error_message": "",
"start_time": "2025-12-01T07:16:11.000000+0000",
"end_time": "2025-12-01T07:16:38.000000+0000"
}
]
},
"request_id": "2934576f-246e-46cf-93d1-79a95fd52251"
}
Example 2: multi-file job completed
{
"code": "OK",
"msg": "OK",
"data": {
"status": "completed",
"files": [
{
"file_id": "019ad8cb-3861-795c-99a6-03bdc37215ee",
"file_name": "report.pdf",
"file_type": 2,
"file_status": "completed",
"error_message": "",
"start_time": "2025-12-01T07:23:38.000000+0000",
"end_time": "2025-12-01T07:24:40.000000+0000"
},
{
"file_id": "019ad8cb-3861-7963-8fa5-e2e6b66a265c",
"file_name": "pdf.pdf",
"file_type": 2,
"file_status": "completed",
"error_message": "",
"start_time": "2025-12-01T07:23:39.000000+0000",
"end_time": "2025-12-01T07:25:38.000000+0000"
}
]
},
"request_id": "74983c96-98db-4e13-9d51-aee91dfcd163"
}
Notes:
A hybrid submission contains both files: a local upload and a remote URL
Each file carries its own
file_id, status, and timing fieldsIn this example both files were processed successfully
Status semantics¶
Overall job status:
Status |
Meaning |
|---|---|
pending |
Submitted, waiting for processing |
processing |
Job is in progress |
completed |
All files completed |
failed |
Job failed |
Per-file status:
Status |
Meaning |
|---|---|
pending |
File waiting for processing |
processing |
File is being processed |
completed |
File processed successfully |
failed |
File processing failed; check |
Notes¶
Polling interval: poll every 3–5 seconds; avoid faster polling
Processing time:
Small files (<1MB) typically take seconds to a minute
Large files may take several minutes
Time depends on file size and complexity
Error handling: if
file_statusisfailed, inspecterror_messagefor the causeTime format: all timestamps are UTC, formatted as
YYYY-MM-DDTHH:MM:SS.ffffff+0000File order: the
filesarray preserves the submission order
End-to-end example¶
# Step 1: submit a job
JOB_ID=$(curl -X POST "https://freetier-01.cn-hangzhou.cluster.matrixonecloud.cn/v1/genai/pipeline" \
-H "Content-Type: application/json" \
-H "moi-key: YOUR_API_KEY" \
-d '{"file_urls": ["http://example.com/file.pdf"], "file_names": [], "steps": [{"node": "ParseNode", "parameters": {}}]}' \
| jq -r '.data.job_id')
echo "Job ID: $JOB_ID"
# Step 2: wait a few seconds
sleep 5
# Step 3: query status
curl -X GET "https://freetier-01.cn-hangzhou.cluster.matrixonecloud.cn/v1/genai/jobs/$JOB_ID" \
-H "moi-key: YOUR_API_KEY" \
| jq '.'
# Step 4: decide based on status whether to keep polling
# - "completed": done
# - "processing": wait and query again
Download Job Results¶
Basics¶
Endpoint:
https://freetier-01.cn-hangzhou.cluster.matrixonecloud.cn/byoa/api/v1/explore/volumes/any/files/{file_id}/rawsMethod:
GETRequest format: URL path parameter
Response format:
application/zip
Headers¶
Name |
Type |
Required |
Description |
|---|---|---|---|
Content-Type |
String |
recommended |
|
moi-key |
String |
yes |
API key for authentication |
Path parameters¶
Name |
Type |
Required |
Description |
|---|---|---|---|
file_id |
String |
yes |
File ID from the |
Response¶
Successful response:
A ZIP archive containing all processing artifacts for the file.
Archive layout:
{file_name}-{file_id}/
├── {file_name}_parse.json # Structured parse output
├── {file_name}.md # Extracted text in Markdown
├── tables/ # Extracted tables (HTML)
│ ├── {table_id_1}.html
│ ├── {table_id_2}.html
│ └── ...
└── images/ # Extracted images
├── {image_hash_1}.jpg
├── {image_hash_2}.jpg
└── ...
Files explained:
File / directory |
Description |
|---|---|
|
Structured parse output; the full parsed document |
|
Extracted text in Markdown — easy to read |
|
Extracted tables; one HTML file per table |
|
Extracted images, named by content hash |
Request examples¶
Example 1: download the result
curl -X GET "https://freetier-01.cn-hangzhou.cluster.matrixonecloud.cn/byoa/api/v1/explore/volumes/any/files/019ad8c4-cf7e-75ca-afa1-5bd971ff9ed9/raws" \
-H "Content-Type: application/json" \
-H "moi-key: YOUR-MOI-KEY" \
-o result.zip
Notes:
-o result.zipsaves the response as a ZIP filefile_idcomes from the status API responseUnzip after download to inspect the contents
Example 2: download and unzip
# 1. Download
curl -X GET "https://freetier-01.cn-hangzhou.cluster.matrixonecloud.cn/byoa/api/v1/explore/volumes/any/files/019ad8c4-cf7e-75ca-afa1-5bd971ff9ed9/raws" \
-H "Content-Type: application/json" \
-H "moi-key: YOUR_API_KEY" \
-o result.zip
# 2. Unzip
unzip result.zip
# 3. List the contents
ls -R
Example 3: list ZIP contents without extracting
curl -s -X GET "https://freetier-01.cn-hangzhou.cluster.matrixonecloud.cn/byoa/api/v1/explore/volumes/any/files/019ad8c4-cf7e-75ca-afa1-5bd971ff9ed9/raws" \
-H "Content-Type: application/json" \
-H "moi-key: YOUR_API_KEY" \
-o result.zip && unzip -l result.zip
Response example¶
ZIP contents listing:
Archive: result.zip
Length Date Time Name
--------- ---------- ----- ----
4463 12-01-2025 07:37 report.pdf-019ad8cb-.../report.pdf_parse.json
940 12-01-2025 07:37 report.pdf-019ad8cb-.../tables/60d46443-0cec-4556-bf7d-bbff5812f9f5.html
784 12-01-2025 07:37 report.pdf-019ad8cb-.../tables/3fef6f19-af8c-4791-b18f-a2747af88fa0.html
3222 12-01-2025 07:37 report.pdf-019ad8cb-.../report.pdf.md
33287 12-01-2025 07:37 report.pdf-019ad8cb-.../images/21ec307c62a48eecbc5f24cedd92eee95706024ab5f041cd17a463e78c377b2f.jpg
38704 12-01-2025 07:37 report.pdf-019ad8cb-.../images/d0be52c9d88f4fe0f7a092863de5679e624a4529552fb863f0d1cdd5ff4fd7cc.jpg
44015 12-01-2025 07:37 report.pdf-019ad8cb-.../images/de217bbf2728e9979cf88d0fc7a81ae5adb5695a329a9ad1863eb079dfd22c22.jpg
--------- -------
125415 7 files
Extracted layout:
report.pdf-019ad8cb-3861-795c-99a6-03bdc37215ee/
├── report.pdf_parse.json (4.4 KB)
├── report.pdf.md (3.2 KB)
├── tables/
│ ├── 60d46443-0cec-4556-bf7d-bbff5812f9f5.html (940 B)
│ └── 3fef6f19-af8c-4791-b18f-a2747af88fa0.html (784 B)
└── images/
├── 21ec307c62a48eecbc5f24cedd92eee95706024ab5f041cd17a463e78c377b2f.jpg (33 KB)
├── d0be52c9d88f4fe0f7a092863de5679e624a4529552fb863f0d1cdd5ff4fd7cc.jpg (38 KB)
└── de217bbf2728e9979cf88d0fc7a81ae5adb5695a329a9ad1863eb079dfd22c22.jpg (44 KB)
Notes¶
file_idsource: call the status API first to obtainfile_idJob state: wait until job status is
completedbefore fetching the archiveArchive size: depends on the source file; archives may include many images
Completeness: the archive contains every output from the ParseNode pipeline
Image naming: images use a content-hash file name to guarantee uniqueness
Save location: use
-oto choose the path and file nameMulti-file jobs: if a job processed multiple files, fetch each archive with its own
file_id