Set PDF metadata
A title typed with extra spaces comes back as Quarterly Report, and the keywords Finance and finance merge into one, keeping the first spelling. Tidy a PDF's properties before it enters an archive or publishing system; the file itself is not changed. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Runs in your browser. Free, unlimited — your data never leaves this page.
Set PDF metadata reliably before a document enters an archive, publishing system, or delivery pipeline. This capability checks that the PDF input uses a supported representation, requires a meaningful non-empty title, and normalizes author, subject, and keyword values into a consistent object. It trims accidental spaces, collapses repeated whitespace, removes blank keywords, and deduplicates keyword variants while preserving their first useful spelling. The result is deterministic and ready for a downstream PDF writer, without network access or changes that depend on runtime state.
Prepare a valid PDF and metadata object
The capability validates the representation but does not download a remote URL or rewrite document bytes. Put the proposed document properties inside the metadata object. The title is mandatory because a blank title defeats the purpose of identifying a file in search results, archives, browser tabs, and document management systems.
Author, subject, and keywords are optional. Every scalar property must be a string; keywords may be either an array of strings or a comma- or semicolon-separated string. Keeping this shape explicit makes failures easy to diagnose before the values reach a PDF-writing stage.
It also separates input transport from descriptive data, so the same normalized metadata can be logged, reviewed, compared, or passed to another capability without extracting it again from a document.
Understand exactly how normalization works
Text normalization is intentionally conservative. Leading and trailing whitespace is removed, and any internal run of spaces, tabs, or line breaks becomes one ordinary space. Letter case, punctuation, accents, and meaningful wording remain unchanged.
An optional author or subject that becomes empty after trimming is omitted from the output instead of being returned as null or an empty placeholder. Keywords receive the same whitespace treatment. Empty entries are discarded, and duplicates are compared without English case differences, so “Annual Report” and “annual report” produce one keyword while the spelling of the first occurrence is preserved.
The title follows the same whitespace rules but cannot disappear: a missing value, a non-string value, or a string containing only whitespace returns an invalid-input error.
Use the normalized result in a safe document pipeline
A downstream writer can take the response, set the corresponding PDF information or XMP fields, and apply its own rules for signatures, encryption, retention, and byte serialization. That division is useful when metadata comes from forms, spreadsheets, content systems, or automated exports: reject malformed records early, review clean values independently, and invoke expensive document processing only for records that pass. It is also helpful in bulk migrations, where inconsistent spacing and repeated keywords create noisy search facets across thousands of documents.
Because this capability performs no network request and stores no state, it can also run consistently in browser and server workflows while producing the same normalized contract for both.
What you can do with it
Validate publishing forms
Check editor-supplied titles and normalize optional descriptive fields before a publishing job writes a final PDF.
Clean archive migrations
Remove spacing inconsistencies and duplicate keywords while preparing legacy document records for a new archive.
Guard automated PDF generation
Stop reports with missing titles before an expensive rendering or PDF metadata-writing stage begins.
FAQ
Does this capability modify the PDF bytes?
No. It validates the PDF representation and returns normalized metadata for a downstream PDF writer.
Which metadata fields are supported?
Title, author, subject, and keywords. Title is required; the other fields are optional.
Can keywords be supplied as one string?
Yes. A string is split on commas or semicolons. You may also provide an array of strings.
How are duplicate keywords handled?
Duplicates are removed case-insensitively after whitespace normalization, while the first spelling and order are preserved.
What happens if the title is empty?
The record is refused. A title is required because a blank one defeats the purpose of identifying a file in search results, archives and browser tabs, and a title made only of spaces counts as empty too.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/pdf/set-metadata \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"pdf":"https://ejemplo.com/documento.pdf","metadata":{"title":"Quarterly Report","author":"Ada Lovelace","subject":"Operations","keywords":["finance","quarterly report"]}}'const res = await fetch("https://api.kit.forhosting.com/pdf/set-metadata", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"pdf": "https://ejemplo.com/documento.pdf",
"metadata": {
"title": "Quarterly Report",
"author": "Ada Lovelace",
"subject": "Operations",
"keywords": [
"finance",
"quarterly report"
]
}
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/pdf/set-metadata",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"pdf": "https://ejemplo.com/documento.pdf",
"metadata": {
"title": "Quarterly Report",
"author": "Ada Lovelace",
"subject": "Operations",
"keywords": [
"finance",
"quarterly report"
]
}
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/pdf/set-metadata", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"pdf":"https://ejemplo.com/documento.pdf","metadata":{"title":"Quarterly Report","author":"Ada Lovelace","subject":"Operations","keywords":["finance","quarterly report"]}}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"pdf":"https://ejemplo.com/documento.pdf","metadata":{"title":"Quarterly Report","author":"Ada Lovelace","subject":"Operations","keywords":["finance","quarterly report"]}}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/pdf/set-metadata", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"pdf": "https://ejemplo.com/documento.pdf",
"metadata": {
"title": "Quarterly Report",
"author": "Ada Lovelace",
"subject": "Operations",
"keywords": [
"finance",
"quarterly report"
]
}
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "pdf.set_metadata",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_mb | 25 |
max_pages | 200 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
Prepare a valid PDF and metadata object
Send the PDF in one of the supported forms: a base64 PDF data URI, a raw string beginning with the PDF signature, an HTTPS URL whose path identifies a PDF, or a kit upload reference.
Understand exactly how normalization works
No clock, random value, external service, or environment-specific state participates in these decisions, so identical JSON input always produces identical JSON output.
Use the normalized result in a safe document pipeline
The response returns the validated PDF representation alongside a metadata object containing the required normalized title and only the optional fields that carry useful content. This is a preparation and validation step, not a binary PDF editor. Calls are priced at $0.002 per item, so cost scales predictably with the number of records validated.
Technical questions
What happens when the title contains only spaces?
The request fails with an invalid_input error because normalization would leave an empty title.
What does one request cost?
Each validated item costs $0.002, with no network or model surcharge.