curl -X POST "https://api-integration.ollang.com/integration/project/60b8d6f1e1b9b1d8c6c0d8e3/docs/upload" \
-H "X-Api-Key: $OLLANG_API_KEY" \
-H "Content-Type: multipart/form-data" \
-F "file=@/path/to/episode-5-slang-notes.pdf" \
-F "type=guideline" \
-F "name=Episode 5 slang notes" \
-F "language=en"
const projectId = "60b8d6f1e1b9b1d8c6c0d8e3";
const formData = new FormData();
formData.append("file", guidelineFile);
formData.append("type", "guideline");
formData.append("name", "Episode 5 slang notes");
formData.append("language", "en");
const response = await fetch(
`https://api-integration.ollang.com/integration/project/${projectId}/docs/upload`,
{
method: "POST",
headers: {
"X-Api-Key": process.env.OLLANG_API_KEY,
},
body: formData,
},
);
const doc = await response.json();
console.log("Attached document:", doc.id);
import os
import requests
project_id = "60b8d6f1e1b9b1d8c6c0d8e3"
files = {'file': open('episode-5-slang-notes.pdf', 'rb')}
data = {
'type': 'guideline',
'name': 'Episode 5 slang notes',
'language': 'en',
}
headers = {'X-Api-Key': os.environ['OLLANG_API_KEY']}
response = requests.post(
f'https://api-integration.ollang.com/integration/project/{project_id}/docs/upload',
files=files,
data=data,
headers=headers,
)
doc = response.json()
print("Attached document:", doc["id"])
$projectId = '60b8d6f1e1b9b1d8c6c0d8e3';
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api-integration.ollang.com/integration/project/{$projectId}/docs/upload",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => array(
'file' => new CURLFile('/path/to/episode-5-slang-notes.pdf'),
'type' => 'guideline',
'name' => 'Episode 5 slang notes',
'language' => 'en',
),
CURLOPT_HTTPHEADER => array(
'X-Api-Key: ' . getenv('OLLANG_API_KEY')
),
));
$response = curl_exec($curl);
$doc = json_decode($response, true);
curl_close($curl);
echo "Attached document: " . $doc['id'];
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"mime/multipart"
"net/http"
"os"
)
func main() {
projectID := "60b8d6f1e1b9b1d8c6c0d8e3"
url := "https://api-integration.ollang.com/integration/project/" + projectID + "/docs/upload"
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
file, _ := os.Open("episode-5-slang-notes.pdf")
defer file.Close()
part, _ := writer.CreateFormFile("file", "episode-5-slang-notes.pdf")
io.Copy(part, file)
writer.WriteField("type", "guideline")
writer.WriteField("name", "Episode 5 slang notes")
writer.WriteField("language", "en")
writer.Close()
req, _ := http.NewRequest("POST", url, body)
req.Header.Set("X-Api-Key", os.Getenv("OLLANG_API_KEY"))
req.Header.Set("Content-Type", writer.FormDataContentType())
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
respBody, _ := io.ReadAll(resp.Body)
var doc map[string]interface{}
json.Unmarshal(respBody, &doc)
fmt.Println("Attached document:", doc["id"])
}
String projectId = "60b8d6f1e1b9b1d8c6c0d8e3";
HttpResponse<String> response = Unirest
.post("https://api-integration.ollang.com/integration/project/" + projectId + "/docs/upload")
.header("X-Api-Key", System.getenv("OLLANG_API_KEY"))
.field("file", new File("episode-5-slang-notes.pdf"))
.field("type", "guideline")
.field("name", "Episode 5 slang notes")
.field("language", "en")
.asString();
JSONObject doc = new JSONObject(response.getBody());
System.out.println("Attached document: " + doc.getString("id"));
{
"id": "60b8d6f1e1b9b1d8c6c0d8f5",
"name": "Episode 5 slang notes.pdf",
"type": "guideline",
"url": "https://ollang-docs.s3.eu-central-1.amazonaws.com/60b8d6f1e1b9b1d8c6c0d8e5/episode-5-slang-notes.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Signature=...",
"size": 90211,
"sourceLanguage": "en",
"projectId": "60b8d6f1e1b9b1d8c6c0d8e3",
"parentDocId": null,
"clientId": "60b8d6f1e1b9b1d8c6c0d8e5",
"createdAt": "2026-10-21T08:02:51.104Z",
"updatedAt": "2026-10-21T08:02:51.104Z"
}
{
"code": -1,
"error": "UnknownError",
"message": "unknown error",
"detail": "File too large"
}
{
"error": "Unauthorized",
"message": "Invalid or missing API key",
"code": "UNAUTHORIZED"
}
{
"statusCode": 403,
"message": "You don't have permission to perform this action. Please contact your account admin.",
"error": "Forbidden"
}
{
"statusCode": 404,
"message": "Project not found",
"error": "Not Found"
}
Ollang API Reference
Upload Project Document
Upload a guideline, glossary, or character list to a single project as a file, without hosting it yourself
POST
/
integration
/
project
/
{projectId}
/
docs
/
upload
curl -X POST "https://api-integration.ollang.com/integration/project/60b8d6f1e1b9b1d8c6c0d8e3/docs/upload" \
-H "X-Api-Key: $OLLANG_API_KEY" \
-H "Content-Type: multipart/form-data" \
-F "file=@/path/to/episode-5-slang-notes.pdf" \
-F "type=guideline" \
-F "name=Episode 5 slang notes" \
-F "language=en"
const projectId = "60b8d6f1e1b9b1d8c6c0d8e3";
const formData = new FormData();
formData.append("file", guidelineFile);
formData.append("type", "guideline");
formData.append("name", "Episode 5 slang notes");
formData.append("language", "en");
const response = await fetch(
`https://api-integration.ollang.com/integration/project/${projectId}/docs/upload`,
{
method: "POST",
headers: {
"X-Api-Key": process.env.OLLANG_API_KEY,
},
body: formData,
},
);
const doc = await response.json();
console.log("Attached document:", doc.id);
import os
import requests
project_id = "60b8d6f1e1b9b1d8c6c0d8e3"
files = {'file': open('episode-5-slang-notes.pdf', 'rb')}
data = {
'type': 'guideline',
'name': 'Episode 5 slang notes',
'language': 'en',
}
headers = {'X-Api-Key': os.environ['OLLANG_API_KEY']}
response = requests.post(
f'https://api-integration.ollang.com/integration/project/{project_id}/docs/upload',
files=files,
data=data,
headers=headers,
)
doc = response.json()
print("Attached document:", doc["id"])
$projectId = '60b8d6f1e1b9b1d8c6c0d8e3';
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api-integration.ollang.com/integration/project/{$projectId}/docs/upload",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => array(
'file' => new CURLFile('/path/to/episode-5-slang-notes.pdf'),
'type' => 'guideline',
'name' => 'Episode 5 slang notes',
'language' => 'en',
),
CURLOPT_HTTPHEADER => array(
'X-Api-Key: ' . getenv('OLLANG_API_KEY')
),
));
$response = curl_exec($curl);
$doc = json_decode($response, true);
curl_close($curl);
echo "Attached document: " . $doc['id'];
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"mime/multipart"
"net/http"
"os"
)
func main() {
projectID := "60b8d6f1e1b9b1d8c6c0d8e3"
url := "https://api-integration.ollang.com/integration/project/" + projectID + "/docs/upload"
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
file, _ := os.Open("episode-5-slang-notes.pdf")
defer file.Close()
part, _ := writer.CreateFormFile("file", "episode-5-slang-notes.pdf")
io.Copy(part, file)
writer.WriteField("type", "guideline")
writer.WriteField("name", "Episode 5 slang notes")
writer.WriteField("language", "en")
writer.Close()
req, _ := http.NewRequest("POST", url, body)
req.Header.Set("X-Api-Key", os.Getenv("OLLANG_API_KEY"))
req.Header.Set("Content-Type", writer.FormDataContentType())
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
respBody, _ := io.ReadAll(resp.Body)
var doc map[string]interface{}
json.Unmarshal(respBody, &doc)
fmt.Println("Attached document:", doc["id"])
}
String projectId = "60b8d6f1e1b9b1d8c6c0d8e3";
HttpResponse<String> response = Unirest
.post("https://api-integration.ollang.com/integration/project/" + projectId + "/docs/upload")
.header("X-Api-Key", System.getenv("OLLANG_API_KEY"))
.field("file", new File("episode-5-slang-notes.pdf"))
.field("type", "guideline")
.field("name", "Episode 5 slang notes")
.field("language", "en")
.asString();
JSONObject doc = new JSONObject(response.getBody());
System.out.println("Attached document: " + doc.getString("id"));
{
"id": "60b8d6f1e1b9b1d8c6c0d8f5",
"name": "Episode 5 slang notes.pdf",
"type": "guideline",
"url": "https://ollang-docs.s3.eu-central-1.amazonaws.com/60b8d6f1e1b9b1d8c6c0d8e5/episode-5-slang-notes.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Signature=...",
"size": 90211,
"sourceLanguage": "en",
"projectId": "60b8d6f1e1b9b1d8c6c0d8e3",
"parentDocId": null,
"clientId": "60b8d6f1e1b9b1d8c6c0d8e5",
"createdAt": "2026-10-21T08:02:51.104Z",
"updatedAt": "2026-10-21T08:02:51.104Z"
}
{
"code": -1,
"error": "UnknownError",
"message": "unknown error",
"detail": "File too large"
}
{
"error": "Unauthorized",
"message": "Invalid or missing API key",
"code": "UNAUTHORIZED"
}
{
"statusCode": 403,
"message": "You don't have permission to perform this action. Please contact your account admin.",
"error": "Forbidden"
}
{
"statusCode": 404,
"message": "Project not found",
"error": "Not Found"
}
Attaches a project document by sending the file itself as
multipart/form-data. Use this when you have the file locally and do not want to host it or generate a pre-signed URL first.
This is the same operation as Attach Project Document; only the way you supply the file differs. The document applies to this project only, together with the guidelines of the project’s folder.
Send the file in a form field named
file. The file must be smaller than
50 MiB (52,428,800 bytes). Files at or above this limit return 413.curl -X POST "https://api-integration.ollang.com/integration/project/60b8d6f1e1b9b1d8c6c0d8e3/docs/upload" \
-H "X-Api-Key: $OLLANG_API_KEY" \
-H "Content-Type: multipart/form-data" \
-F "file=@/path/to/episode-5-slang-notes.pdf" \
-F "type=guideline" \
-F "name=Episode 5 slang notes" \
-F "language=en"
const projectId = "60b8d6f1e1b9b1d8c6c0d8e3";
const formData = new FormData();
formData.append("file", guidelineFile);
formData.append("type", "guideline");
formData.append("name", "Episode 5 slang notes");
formData.append("language", "en");
const response = await fetch(
`https://api-integration.ollang.com/integration/project/${projectId}/docs/upload`,
{
method: "POST",
headers: {
"X-Api-Key": process.env.OLLANG_API_KEY,
},
body: formData,
},
);
const doc = await response.json();
console.log("Attached document:", doc.id);
import os
import requests
project_id = "60b8d6f1e1b9b1d8c6c0d8e3"
files = {'file': open('episode-5-slang-notes.pdf', 'rb')}
data = {
'type': 'guideline',
'name': 'Episode 5 slang notes',
'language': 'en',
}
headers = {'X-Api-Key': os.environ['OLLANG_API_KEY']}
response = requests.post(
f'https://api-integration.ollang.com/integration/project/{project_id}/docs/upload',
files=files,
data=data,
headers=headers,
)
doc = response.json()
print("Attached document:", doc["id"])
$projectId = '60b8d6f1e1b9b1d8c6c0d8e3';
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api-integration.ollang.com/integration/project/{$projectId}/docs/upload",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => array(
'file' => new CURLFile('/path/to/episode-5-slang-notes.pdf'),
'type' => 'guideline',
'name' => 'Episode 5 slang notes',
'language' => 'en',
),
CURLOPT_HTTPHEADER => array(
'X-Api-Key: ' . getenv('OLLANG_API_KEY')
),
));
$response = curl_exec($curl);
$doc = json_decode($response, true);
curl_close($curl);
echo "Attached document: " . $doc['id'];
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"mime/multipart"
"net/http"
"os"
)
func main() {
projectID := "60b8d6f1e1b9b1d8c6c0d8e3"
url := "https://api-integration.ollang.com/integration/project/" + projectID + "/docs/upload"
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
file, _ := os.Open("episode-5-slang-notes.pdf")
defer file.Close()
part, _ := writer.CreateFormFile("file", "episode-5-slang-notes.pdf")
io.Copy(part, file)
writer.WriteField("type", "guideline")
writer.WriteField("name", "Episode 5 slang notes")
writer.WriteField("language", "en")
writer.Close()
req, _ := http.NewRequest("POST", url, body)
req.Header.Set("X-Api-Key", os.Getenv("OLLANG_API_KEY"))
req.Header.Set("Content-Type", writer.FormDataContentType())
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
respBody, _ := io.ReadAll(resp.Body)
var doc map[string]interface{}
json.Unmarshal(respBody, &doc)
fmt.Println("Attached document:", doc["id"])
}
String projectId = "60b8d6f1e1b9b1d8c6c0d8e3";
HttpResponse<String> response = Unirest
.post("https://api-integration.ollang.com/integration/project/" + projectId + "/docs/upload")
.header("X-Api-Key", System.getenv("OLLANG_API_KEY"))
.field("file", new File("episode-5-slang-notes.pdf"))
.field("type", "guideline")
.field("name", "Episode 5 slang notes")
.field("language", "en")
.asString();
JSONObject doc = new JSONObject(response.getBody());
System.out.println("Attached document: " + doc.getString("id"));
Authorizations
This endpoint requires API key authentication. Include your API key in the request header:- Header name:
X-Api-Key - Header value: Your API key from the Ollang dashboard
- Format:
X-Api-Key: your-api-key-here
OLLANG_API_KEY environment variable; set it before running them.
The project must belong to the API key’s account; other projects return 404.
The API key user also needs write access, the same as for folder documents: the
account owner, team-manager or order-creator role, or project manager of the
project’s folder. Other keys, such as view-only users, receive a 403.
Path Parameters
string
required
The unique identifier of the project to attach the document to. Retrieve
project IDs with Retrieve All
Projects.
Body Parameters
Send the request asmultipart/form-data.
file
required
The document to upload, smaller than 50 MiB (52,428,800 bytes).
string
required
The kind of project document. One of:
guideline— style and tone guidanceguideline_glossary— terminology listcharacter_list— character names and notes
string
Display name of the document. Defaults to the uploaded file’s own name. The
file’s extension is appended when the name does not already end with it.
string
BCP-47 language tag of the document (e.g.
en). Defaults to the project’s
source language.Response
Returns the created project document, identical to Attach Project Document.string
Unique identifier of the project document. Pass this to Update Project
Document or Remove
Project Document.
string
Display name of the document.
string
One of
guideline, guideline_glossary, or character_list.string
A pre-signed download link for the stored copy Ollang created, valid for 12
hours.
number
Size of the stored document in bytes.
string
The
language supplied with the request, or the project’s source language.string
Identifier of the project the document is attached to.
string
When the document was attached, in ISO 8601 format.
{
"id": "60b8d6f1e1b9b1d8c6c0d8f5",
"name": "Episode 5 slang notes.pdf",
"type": "guideline",
"url": "https://ollang-docs.s3.eu-central-1.amazonaws.com/60b8d6f1e1b9b1d8c6c0d8e5/episode-5-slang-notes.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Signature=...",
"size": 90211,
"sourceLanguage": "en",
"projectId": "60b8d6f1e1b9b1d8c6c0d8e3",
"parentDocId": null,
"clientId": "60b8d6f1e1b9b1d8c6c0d8e5",
"createdAt": "2026-10-21T08:02:51.104Z",
"updatedAt": "2026-10-21T08:02:51.104Z"
}
{
"code": -1,
"error": "UnknownError",
"message": "unknown error",
"detail": "File too large"
}
{
"error": "Unauthorized",
"message": "Invalid or missing API key",
"code": "UNAUTHORIZED"
}
{
"statusCode": 403,
"message": "You don't have permission to perform this action. Please contact your account admin.",
"error": "Forbidden"
}
{
"statusCode": 404,
"message": "Project not found",
"error": "Not Found"
}
Was this page helpful?