Web API
Two HTTP requests are all it takes to have DS Server convert a document: one for an access token, one for the conversion. The steps below send them with curl in a bash shell, convert an HTML document to PDF and save the result, and then repeat the same requests in JavaScript with Node.js. Whatever language your application is written in, the requests stay the same, so the commands also show what your own HTTP client has to send.
Prerequisites
- A DS Server. Either a DS Server of your own that is installed and registered, as the Installation Guide and Licensing describe, or a trial token for the trial server
https://trial.dsserver.io. - A security profile that allows the client credentials grant type. On your own server, create it in the admin portal and turn on Allow "Client Credentials" grant type, as Create a Security Profile shows. The trial profile allows it already.
- A bash shell with curl, jq and GNU base64, as on Linux or in the Windows Subsystem for Linux. jq reads the JSON responses; base64 encodes and decodes the documents.
Set the Connection Details
Open a terminal and store the address of DS Server and the credentials of the security profile in shell variables, so that the following commands can use them:
DS_URL="http://localhost:5000"
CLIENT_ID="<client ID>"
CLIENT_SECRET="<client secret>"
Replace http://localhost:5000 with the address of your DS Server, or with https://trial.dsserver.io for a trial token, and the placeholders with the client ID and the client secret of the profile. Client IDs that the admin portal creates start with dsserver..
Request an Access Token
DS Server issues access tokens at the endpoint /oauth/token. With the client credentials grant type, you send the client ID and the client secret as an HTTP Basic Authorization header, which the --user option of curl creates, and the grant type as form data:
curl POST "$DS_URL/oauth/token" \
"$CLIENT_ID:$CLIENT_SECRET" \
grant_type=client_credentials
DS Server answers with the access token:
{
"access_token": "<access token>",
"token_type": "Bearer",
"expires_in": "3600"
}
The token is valid for 3,600 seconds, one hour. Send the request again with jq at the end to store the token in a variable:
ACCESS_TOKEN=$(curl POST "$DS_URL/oauth/token" \
"$CLIENT_ID:$CLIENT_SECRET" \
grant_type=client_credentials | jq .access_token)
The client ID and the client secret must be in the header. Sent only as the form fields client_id and client_secret, DS Server rejects the request with Missing authorization header.
Convert a Document to PDF
The endpoint POST /documentprocessing/document/convert takes a document as a Base64-encoded string in a JSON body and returns the converted document the same way. The format of the result is the query parameter returnFormat.
Create the document to convert, a small HTML file:
printf '<h1>Invoice 1001</h1>\n<p>Thank you for your order.</p>\n' > invoice.htmlEncode it as Base64 and put it in quotes, which makes it a JSON string, in the file request.json:
printf '"%s"' "$(base64 -w 0 invoice.html)" > request.jsonSend it to DS Server with the access token in a
Bearerheader:curl POST "$DS_URL/documentprocessing/document/convert?returnFormat=PDF" \ "Authorization: Bearer $ACCESS_TOKEN" \ "Content-Type: application/json" \ @request.json \ response.json \ '%{http_code}\n'curl saves the response body in response.json and prints the status code,
200when the conversion succeeded.Decode the Base64 string of the response into the PDF file:
jq . response.json | base64 > invoice.pdf
Open invoice.pdf in a PDF viewer: it shows the heading "Invoice 1001" and the line below it.
What the Requests Do
- The token request posts
grant_type=client_credentialsasapplication/x-www-form-urlencodeddata to/oauth/token. A JSON body is not accepted there. - The conversion request posts the document as a JSON string, such as
"PGgxPkludm9pY2Ug...", and passes the access token asAuthorization: Bearer <access token>. Instead of the header, you can append the token as the query parameteraccess_token. - The response is a JSON string again: the PDF encoded as Base64.
jq -r .removes the quotes, andbase64 --decodeturns the string back into binary data. returnFormatacceptsPDF,PDFA,RTF,DOC,DOCX,HTML,TXandTXT; it defaults toPDF. The input can be RTF, DOC, DOCX, HTML, PDF or the TX Text Control format; Supported File Formats lists what the Core build on Linux supports.
To convert a Word document, encode it instead of invoice.html in step 2. base64 -w 0 works for binary files as well.
The Same Requests in JavaScript
Every language with an HTTP client sends the same two requests. The following script does it with the fetch function of Node.js 20 or later and needs no package. Save it as convert.mjs in the folder that holds invoice.html:
import { readFile, writeFile } from "node:fs/promises";
const dsUrl = "http://localhost:5000";
const clientId = "<client ID>";
const clientSecret = "<client secret>";
// Request an access token with the client credentials grant type
const tokenResponse = await fetch(`${dsUrl}/oauth/token`, {
method: "POST",
headers: {
"Authorization": "Basic " + Buffer.from(`${clientId}:${clientSecret}`).toString("base64"),
"Content-Type": "application/x-www-form-urlencoded"
},
body: "grant_type=client_credentials"
});
if (!tokenResponse.ok) throw new Error(await tokenResponse.text());
const { access_token } = await tokenResponse.json();
// Send the HTML document as a Base64-encoded JSON string
const html = await readFile("invoice.html");
const convertResponse = await fetch(`${dsUrl}/documentprocessing/document/convert?returnFormat=PDF`, {
method: "POST",
headers: {
"Authorization": `Bearer ${access_token}`,
"Content-Type": "application/json"
},
body: JSON.stringify(html.toString("base64"))
});
if (!convertResponse.ok) throw new Error(await convertResponse.text());
// The response is the PDF document as a Base64-encoded JSON string
const pdf = await convertResponse.json();
await writeFile("invoice.pdf", Buffer.from(pdf, "base64"));
console.log("Saved invoice.pdf");
Replace the service URL and the credentials, and run the script:
node convert.mjs
The script prints Saved invoice.pdf and writes the same PDF as the curl commands. Run it on a server, not in a browser page: the client secret must not reach the browser.
Troubleshooting
DS Server answers errors of the token request with status code 400 and a JSON body that names the error:
{
"error": "unsupported_grant_type",
"error_description": "This security profile does not allow the specified grant type. (client_credentials)"
}
| Response | Cause | Fix |
|---|---|---|
400, unsupported_grant_type | The security profile doesn't allow the client credentials grant type | Turn on Allow "Client Credentials" grant type in the profile |
400, invalid_client, Invalid client ID. or Invalid client secret. | The client ID or the client secret is wrong | Copy both again from the profile in the admin portal |
400, invalid_request, Missing authorization header. | The credentials were sent as form fields only | Send them as a Basic header, --user in curl |
| 401 with an empty body | OAuth is enabled and the access token is missing, wrong or expired, or the security profile has expired | Request a new token and send it as Authorization: Bearer <access token> |
400, DS Server is not registered. | DS Server has no license yet | Register the server, as Licensing describes |
400, One or more validation errors occurred. | The body is not a JSON string, for example {} | Put the Base64 string in quotes, as step 2 does |
When DS Server answers an error, response.json holds its message instead of a document, and base64 --decode reports invalid input. Look at the file with cat response.json.
Next Steps
- Authentication: access tokens, grant types and how to reuse a token until it expires.
- Converting Documents: formats, options and form fields.
- Merging Templates: fill a template with JSON data.
- POST /documentprocessing/document/convert and POST /oauth/token: the parameters and responses of the two endpoints.
- ASP.NET Core: the same conversion with the .NET package.