API Reference

HMAC-authenticated endpoints with robust error semantics.

Overview

HMAC-authenticated endpoint to remove a PDF password and return the unlocked file.

  • Auth HMAC-SHA256 (key + secret)
  • Content multipart/form-data
  • Rate-limit Per API key

Rate limits

  • Quota: 5 calls / day per API key
  • Window: UTC day (resets at 00:00 UTC)
  • Exceeding: HTTP 429 with JSON error
HeaderMeaning
X-RateLimit-LimitDaily quota (always 5 by default)
X-RateLimit-RemainingCalls left today after this request
X-RateLimit-ResetUnix epoch seconds of next UTC reset
Note: This API is for developers and public use with limits. Postman does not work for file uploads with this HMAC scheme, because it re-encodes multipart/form-data and the raw bytes you sign won’t match the bytes sent. Use the code samples below (Python / Node.js / Go) in your application.

API keys

Allowed: a-z, 0-9, -. Max 16 chars. Must be unique.
CreatedLabelAPI KeySecretAction
No keys yet. Create one above to get started.

Keys authenticate calls to /api/v1/remove_password using HMAC headers.
Successful unlocks decrement the daily quota. See X-RateLimit-* response headers.

POST

Remove PDF Password

/api/v1/remove_password

Upload a password-protected PDF and receive the unlocked file. One PDF and one password per request.

HMAC headers Form data JSON errors 5 calls/day

Headers

NameDescription
X-API-KEYYour issued key id
X-API-TIMESTAMPUNIX seconds or ISO-8601 UTC (±300s)
X-API-SIGNATUREhex HMAC-SHA256 of UPPER(method)\npath\ntimestamp\nsha256_hex(raw_body)
Content-Typemultipart/form-data (the request body you signed)

Form fields

FieldDescription
filePDF file (required)
passwordCurrent PDF password (required)
Python
import time, hmac, hashlib, requests, os
from requests_toolbelt import MultipartEncoder

API_KEY = "<your_api_key>"
API_SECRET = "<your_api_secret>"
PATH = "/api/v1/remove_password"
URL  = "https://api.yourdomain.com" + PATH

FILE_PATH = "protected.pdf"
PDF_PASSWORD = "mypassword"

m = MultipartEncoder(fields={
    "file": (os.path.basename(FILE_PATH), open(FILE_PATH, "rb"), "application/pdf"),
    "password": PDF_PASSWORD,
})
body = m.to_string()
body_hash = hashlib.sha256(body).hexdigest()
ts = str(int(time.time()))
msg = f"POST\n{PATH}\n{ts}\n{body_hash}"
sig = hmac.new(API_SECRET.encode(), msg.encode(), hashlib.sha256).hexdigest()

headers = {
    "X-API-KEY": API_KEY,
    "X-API-TIMESTAMP": ts,
    "X-API-SIGNATURE": sig,
    "Content-Type": m.content_type,
}

r = requests.post(URL, headers=headers, data=body, timeout=180)
if r.ok and r.headers.get("Content-Type","").startswith("application/pdf"):
    open("unlocked.pdf", "wb").write(r.content)
else:
    print(r.status_code, r.text)
HTTP
HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Disposition: attachment; filename="unlocked.pdf"
X-RateLimit-Limit: 5
X-RateLimit-Remaining: 4
X-RateLimit-Reset: <epoch>

%PDF-1.7 ... (binary)
Bad signature401
HTTP
HTTP/1.1 401 Unauthorized
Content-Type: application/json

{
  "error": "bad_signature: HMAC does not match. Recompute using UPPER(method)\npath\ntimestamp\nsha256_hex(raw_body) with your plaintext api_secret.",
}
Timestamp skew401
HTTP
HTTP/1.1 401 Unauthorized
Content-Type: application/json

{
  "error": "skew: Timestamp outside allowed window (±300s). Use current UNIX seconds or ISO-8601 UTC.",
}
Missing file or password400
HTTP
HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "error": "Missing file or password"
}
Incorrect password400
HTTP
HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "error": "Incorrect password"
}
Only PDF files are supported400
HTTP
HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "error": "Only PDF files are supported"
}
Too many requests today429
HTTP
HTTP/1.1 429 Too Many Requests
Content-Type: application/json

{
  "error": "daily_quota_exceeded",
  "message": "You have exceeded your daily API calls"
}
Processing timeout504
HTTP
HTTP/1.1 504 Gateway Timeout
Content-Type: application/json

{
  "error": "processing_timeout"
}

Error meanings

  • skew: Timestamp is outside the allowed ±300s window. Client clock out of sync or stale signature.
  • bad_signature: HMAC does not match. Compute using UPPER(method)\npath\ntimestamp\nsha256_hex(raw_body) and the plaintext api_secret.
Copied to clipboard.