TypeScript SDK
What You Will Build
This quickstart shows how to use the FormKiQ TypeScript Client SDK with the FormKiQ Documents API.
You will:
- Configure a TypeScript SDK client
- Create a small inline document
- Retrieve document metadata
- Request a presigned S3 upload URL
- Upload file bytes directly to S3
- Verify the uploaded document
This walkthrough uses JWT authentication. If you need a token, see JWT Authentication Token.
Before You Begin
- Node.js 18 or later
- npm or yarn
- A FormKiQ API base URL
- A valid JWT access token, not an ID token
- A
siteId, ordefaultif your deployment does not use multiple sites - Network access to the FormKiQ API and Amazon S3
Workflow Overview
- Install the TypeScript SDK and runtime tooling.
- Configure the SDK client with your API URL and JWT access token.
- Create a small inline document.
- Retrieve document metadata.
- Request a presigned S3 upload URL.
- Upload file bytes to S3.
- Verify the uploaded document metadata.
Step 1: Install the SDK
Create a project if you do not already have one:
mkdir formkiq-typescript-example
cd formkiq-typescript-example
npm init -y
Install the SDK, Axios, and TypeScript runtime tooling:
npm install axios @formkiq/client-sdk-typescript
npm install --save-dev typescript tsx @types/node
Set the environment variables used by the examples:
export FORMKIQ_API_URL="https://your-formkiq-api.example.com"
export JWT="REPLACE_WITH_ACCESS_TOKEN"
export SITE_ID="default"
Use a JWT access token. An ID token will not authorize FormKiQ API calls.
Step 2: Configure the Client
Import the SDK and create a configured DocumentsApi client.
import fs from "node:fs";
import axios from "axios";
import { Configuration, DocumentsApi } from "@formkiq/client-sdk-typescript";
const formkiqApiUrl = process.env.FORMKIQ_API_URL;
const jwtAccessToken = process.env.JWT;
const siteId = process.env.SITE_ID || "default";
if (!formkiqApiUrl) {
throw new Error("FORMKIQ_API_URL is required");
}
if (!jwtAccessToken) {
throw new Error("JWT is required");
}
const configuration = new Configuration({
basePath: formkiqApiUrl,
baseOptions: {
headers: {
Authorization: `Bearer ${jwtAccessToken}`,
},
},
});
const documentsApi = new DocumentsApi(configuration);
Step 3: Create an Inline Document
Use addDocument for small documents where sending content through the API is appropriate.
async function addInlineDocument(api: DocumentsApi, currentSiteId: string): Promise<string> {
const response = await api.addDocument(
{
path: "inbox/hello.txt",
contentType: "text/plain",
content: "Hello World",
},
currentSiteId
);
const documentId = response.data.documentId;
if (!documentId) {
throw new Error("Missing documentId in addDocument response");
}
return documentId;
}
Step 4: Retrieve Document Metadata
Use getDocument to retrieve the document record.
async function getDocumentMetadata(
api: DocumentsApi,
currentSiteId: string,
documentId: string
): Promise<unknown> {
const response = await api.getDocument(documentId, currentSiteId);
return response.data;
}
Step 5: Upload a Larger File
For larger files, request a presigned S3 upload URL. This sends file bytes directly to S3 instead of sending them through the FormKiQ API.
type PresignedUpload = {
documentId: string;
url: string;
headers: Record<string, string>;
};
async function requestPresignedUpload(
api: DocumentsApi,
currentSiteId: string,
path: string,
contentType: string,
contentLength: number
): Promise<PresignedUpload> {
const response = await api.addDocumentUpload(
{
path,
contentType,
contentLength,
},
currentSiteId
);
const documentId = response.data.documentId;
const url = response.data.url;
const headers = (response.data.headers || {}) as Record<string, string>;
if (!documentId) {
throw new Error("Missing documentId in addDocumentUpload response");
}
if (!url) {
throw new Error("Missing url in addDocumentUpload response");
}
return { documentId, url, headers };
}
When the presigned upload response includes headers, send those headers exactly as returned. Omitting or changing required headers can cause Amazon S3 to reject the upload.
Upload the file bytes with HTTP PUT:
async function s3PutBytes(
url: string,
data: Buffer,
contentType: string,
returnedHeaders: Record<string, string>
): Promise<void> {
await axios.put(url, data, {
headers: {
"Content-Type": contentType,
...returnedHeaders,
},
maxBodyLength: Infinity,
});
}
Step 6: Run the Example
This example creates one inline document, uploads one local file through S3, and retrieves metadata for both documents.
async function main(): Promise<void> {
console.log("Using API:", formkiqApiUrl);
console.log("\nStep 1: Create an inline document");
const inlineDocumentId = await addInlineDocument(documentsApi, siteId);
console.log("Inline documentId:", inlineDocumentId);
console.log("\nStep 2: Retrieve inline document metadata");
console.log(await getDocumentMetadata(documentsApi, siteId, inlineDocumentId));
const uploadLocalPath = "example.ts";
const uploadDestPath = "examples/example.ts";
const uploadContentType = "text/plain";
const fileBytes = fs.readFileSync(uploadLocalPath);
console.log("\nStep 3: Request a presigned S3 upload URL");
const presign = await requestPresignedUpload(
documentsApi,
siteId,
uploadDestPath,
uploadContentType,
fileBytes.length
);
console.log("Upload documentId:", presign.documentId);
console.log("\nStep 4: Upload bytes directly to S3");
await s3PutBytes(presign.url, fileBytes, uploadContentType, presign.headers);
console.log("Upload complete");
console.log("\nStep 5: Verify uploaded document metadata");
console.log(await getDocumentMetadata(documentsApi, siteId, presign.documentId));
}
main().catch((error) => {
console.error("Example failed:", error);
process.exitCode = 1;
});
Run the example:
npx tsx example.ts
The full TypeScript example is available in the FormKiQ TypeScript SDK repository.
Verify the Result
Confirm that the script prints two document IDs and metadata for both documents. In the FormKiQ console, the uploaded document should appear at examples/example.ts in the selected site.
Clean Up
Delete the test documents from the FormKiQ console or API if you do not want to keep them in your environment.
Troubleshooting
401 Unauthorized
The JWT is missing, expired, or is not an access token. Confirm JWT is set and the SDK sends Authorization: Bearer <token>.
403 Forbidden
The token is valid, but the caller does not have access to the requested siteId or operation. Verify the user, group, or token permissions.
Wrong API URL
Confirm FORMKIQ_API_URL is the API endpoint for the authentication method you are using. A JWT token should be sent to the JWT-enabled API URL.
S3 Upload Failed
Use the exact presigned URL returned by FormKiQ. Include any returned headers, keep the same content type, set maxBodyLength for larger uploads, and do not reuse an expired presigned URL.
Missing Document ID
If the SDK response shape differs from the examples, inspect the response object from your installed SDK version and use the returned documentId field.
Next Steps
- Review the API Reference
- Add document attributes during create or upload
- Search uploaded documents with Search
- Route documents with Rulesets and Workflows
- Compare the Python SDK
- Compare the Java SDK