tmsign Documentation

Version v1

Get Started

Overview

Use the tmsign API to create signing requests, deliver signature journeys, track status changes, and retrieve final signed documents inside your own application.

Base URL

https://dev.api.tmsign.co.uk

Version

v1

Support

Contact integration team

SDK Ready Integration-first API with OAuth, webhooks, and signed delivery.

Build e-signature flows into your product with a docs experience that feels like a real developer portal.

This portal is built for third-party teams integrating tmsign signing journeys. The focus is on clear workflow guidance, consistent request patterns, and production-ready event tracking.

Who this is for

Partners, platform teams, and internal product teams embedding signing.

Typical use cases

Onboarding, contracts, identity verification, and regulated approvals.

Docs structure

One click nav, clear flows, and concrete payload examples.

Get Started

Getting Started

You will receive a company ID plus a client ID and client secret from the tmsign team. Use those to request an access token and start creating signing requests.

1

Get credentials

Request a `client_id`, `client_secret`, and `x-company-id` from the integration team.

2

Create access token

Call `POST /v1/auth/token` with the `client_credentials` grant type.

3

Send documents

Use `POST /v1/documents` with files and signer data to start a signing flow.

4

Track & download

Poll document status or receive webhook events, then download the signed PDF.

Get Started

Core Workflow

A clear end-to-end path from authentication to signed PDFs.

1

Authenticate

Exchange client credentials for an access token.

2

Create Document

Upload PDFs or use templates with signer details.

3

Send to Signers

Signers receive email/SMS based on delivery settings.

4

Track Status

Poll `/v1/documents/{id}` or receive webhooks.

5

Download

Get the signed document when status is `Completed`.

Development

Authentication

The API follows OAuth-style token exchange. The recommended integration grant is `client_credentials`.

Token Request

curl -X POST https://dev.api.tmsign.co.uk/v1/auth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "client_credentials",
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET",
    "scope": "company"
  }'

Token Response

{
  "access_token": "eyJhbGciOi...",
  "refresh_token": "eyJhbGciOi...",
  "token_type": "Bearer",
  "expires_in": 3600
}
Other supported grant types: `otp`, `password`, `refresh_token`, `pin`.

Using the API

API Overview

Quick lookup for the primary endpoints used in integrations.

Endpoint Method Description
/v1/auth/token POST Issue access tokens for OAuth-style auth.
/v1/documents POST Create a document with signers and attachments.
/v1/documents/{id} GET Fetch document status and signer progress.
/v1/documents/{id}/download GET Download the signed document when completed.
/v1/esign-templates GET List available templates for reuse.
/v1/esign-templates/{id} GET Retrieve template details and roles.
/v1/company GET Get company profile and settings.
/v1/users/me GET Return details of the authenticated user.

Response envelope

Most endpoints return `{ data, metadata }`. List endpoints return `{ data, metadata }` with pagination.

Using the API

API Reference

All endpoints grouped by controller/tag. Each entry lists parameters, request bodies, and responses.

Authentication

7 endpoints

POST /v1/auth/logout Logout user Authentication

Revoke user's refresh token and logout

Auth: PublicBody: application/json

Request Body

Content-Typeapplication/json
SchemaLogoutRequest
RequiredYes
Fields
FieldTypeRequiredDescription
refreshTokenstringYesRefresh token to revoke

Responses

200Logout successful | application/json | ApiResponse_null_
400Invalid request | application/json | ApiResponse_ErrorResponse_
401Invalid refresh token | application/json | ApiResponse_ErrorResponse_
500Server error | application/json | ApiResponse_ErrorResponse_
Example 200 response
{
  "data": null
}
POST /v1/auth/request-password-reset RequestPasswordReset Authentication
Auth: PublicBody: application/json

Request Body

Content-Typeapplication/json
RequiredYes
Fields
FieldTypeRequiredDescription
captchaTokenstringYes
emailstringYes

Responses

200Ok | application/json | ApiResponse__message-string__
400Invalid request | application/json | ApiResponse_ErrorResponse_
500Server error | application/json | ApiResponse_ErrorResponse_
Example 200 response
{
  "data": {
    "message": "If an account exists with this email, a password reset link will be sent"
  },
  "metadata": {
    "requestId": "123e4567-e89b-12d3-a456-426614174000",
    "timestamp": "2026-04-07T15:56:50.018Z"
  }
}
POST /v1/auth/reset-password ResetPassword Authentication
Auth: PublicBody: application/json

Request Body

Content-Typeapplication/json
RequiredYes
Fields
FieldTypeRequiredDescription
captchaTokenstringYes
passwordstringYes
tokenstringYes

Responses

200Ok | application/json | ApiResponse__message-string__
400Invalid request | application/json | ApiResponse_ErrorResponse_
401Invalid or expired token | application/json | ApiResponse_ErrorResponse_
500Server error | application/json | ApiResponse_ErrorResponse_
Example 200 response
{
  "data": {
    "message": "Password has been reset successfully"
  },
  "metadata": {
    "requestId": "123e4567-e89b-12d3-a456-426614174000",
    "timestamp": "2026-04-07T15:56:50.019Z"
  }
}
POST /v1/auth/setup-pin PIN Setup Authentication

Set up a PIN for a user

Auth: jwtBody: application/json

Request Body

Content-Typeapplication/json
SchemaPublicSetupPinRequest
RequiredYes
Fields
FieldTypeRequiredDescription
emailstringYesUser's email address Pattern: ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
pinstringYesUser's new PIN code (6 digits) Pattern: ^\d{6}$ Example: 123456
telephoneNumberstringNoUser's telephone number in E.164 format (Optional) Pattern: ^\+[1-9]\d{1,14}$
nationalitystringNoUser's nationality (ISO 3166-1 alpha-2) (Optional)

Responses

200PIN set up successfully | application/json | ApiResponse_TokenData_
400Invalid request or PIN already exists | application/json | ApiResponse_ErrorResponse_
401Unauthorized | application/json | ApiResponse_ErrorResponse_
Example 200 response
{
  "data": {
    "message": "PIN set up successfully"
  }
}
POST /v1/auth/signup Register new user Authentication

Register a new user with email verification

Auth: PublicBody: application/json

Request Body

Content-Typeapplication/json
SchemaSignupRequest
RequiredYes
Fields
FieldTypeRequiredDescription
emailstringYesUser's email address Pattern: ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
passwordstringYesUser's password Pattern: ^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!%*#?&]{8,}$
namestringYesUser's full name
telephoneNumberstringNoUser's telephone number in E.164 format Pattern: ^\+[1-9]\d{1,14}$
nationalitystringNoUser's nationality (ISO 3166-1 alpha-2)
companyNamestringYesCompany name
captchaTokenstringYesCAPTCHA token for verification

Responses

201User created successfully | application/json | ApiResponse__message-string--email-string--status-string_-or-ErrorResponse_
400Invalid request | application/json | ApiResponse_ErrorResponse_
409User already exists | application/json | ApiResponse_ErrorResponse_
500Server error | application/json | ApiResponse_ErrorResponse_
Example 201 response
{
  "data": {
    "message": "User created successfully",
    "email": "user@example.com",
    "status": "pending_verification"
  }
}
POST /v1/auth/token Get OAuth token Authentication

OAuth 2.0 token endpoint supporting multiple grant types

Auth: PublicBody: application/json

Request Body

Content-Typeapplication/json
SchemaTokenRequest
RequiredYes
Fields
FieldTypeRequiredDescription
grant_typestringYesOAuth grant type ('otp', 'password', 'refresh_token', 'client_credentials', or 'pin') Allowed: otp, password, refresh_token, client_credentials, pin
usernamestringNoUsername (email) for authentication - required for password and pin grant
passwordstringNoUser password - required for password grant if user has a password set Pattern: ^(?=.*[A-Za-z])(?=.*\d)(?=.*[^A-Za-z\d])[^\s]{8,}$
pinstringNoUser's PIN / Passcode - required for pin grant (6 digits) Pattern: ^\d{6}$ Example: 123456
refresh_tokenstringNoRefresh token - required for refresh_token grant
client_idstringNoClient ID - required for client_credentials grant
client_secretstringNoClient Secret - required for client_credentials grant
scopestringNoSpace-separated list of requested scopes

Responses

200Token generated successfully | application/json | ApiResponse_TokenResponse-or-ErrorResponse-or-OTPVerificationResponse_
400Invalid request | application/json | ApiResponse_ErrorResponse_
401Invalid credentials | application/json | ApiResponse_ErrorResponse_
500Server error | application/json | ApiResponse_ErrorResponse_
Example 200 response
{
  "data": {
    "access_token": "your.access.token",
    "token_type": "Bearer",
    "expires_in": 3600,
    "refresh_token": "your.refresh.token"
  }
}
POST /v1/auth/verify-otp Verify OTP Authentication

Verify OTP code for user authentication

Auth: PublicBody: application/json

Request Body

Content-Typeapplication/json
SchemaVerifyOTPRequest
RequiredYes
Fields
FieldTypeRequiredDescription
emailstringYesUser's email address
otpCodestringYesOTP code sent to the user
isRememberbooleanNoKeep cookie longer. Default 2 hours. is remember true keep 7 days

Responses

200OTP verified successfully | application/json | ApiResponse_TokenResponse_
400Invalid request | application/json | ApiResponse_ErrorResponse_
401Invalid OTP code | application/json | ApiResponse_ErrorResponse_
500Server error | application/json | ApiResponse_ErrorResponse_
Example 200 response
{
  "data": {
    "access_token": "your.access.token",
    "token_type": "Bearer",
    "expires_in": 3600,
    "refresh_token": "your.refresh.token"
  }
}

Users

17 endpoints

GET /v1/users Get all users Users

Retrieve all users within a specific company

Auth: jwt (scopes: lawtech-admin, company-admin, company)Params: 5

Parameters

x-company-id (header)string, required — The company ID from x-company-id header
page (query)number (double) — The page number for pagination (default: 1)
limit (query)number (double) — The number of items per page (default: 10)
isActive (query)boolean
type (query)array<string>

Responses

200Success | application/json | PaginatedResponse_UserResponse-Array_
400Company ID is required | application/json | ApiResponse_null_
401Unauthorized | application/json | ApiResponse_null_
Example 200 response
{
  "data": [
    {
      "id": "123",
      "email": "user@example.com",
      "name": "John Doe",
      "telephoneNumber": "+1234567890",
      "isActive": true,
      "createdAt": "2026-04-07T15:56:49.855Z",
      "updatedAt": "2026-04-07T15:56:49.855Z",
      "nationality": "UK"
    }
  ],
  "metadata": {
    "total": 100,
    "page": 1,
    "limit": 10,
    "totalPages": 10,
    "timestamp": "2026-04-07T15:56:49.855Z"
  }
}
POST /v1/users Create user Users

Create a new user

Auth: jwt (scopes: lawtech-admin, company-admin, company-user)Body: application/jsonParams: 1

Parameters

x-company-id (header)string, required — The company ID from x-company-id header

Request Body

Content-Typeapplication/json
SchemaCreateUserRequest
RequiredYes
Fields
FieldTypeRequiredDescription
emailstringYesThe user's email address
namestringYesThe user's full name
passwordstringNoThe user's password
telephoneNumberstringNoThe user's telephone number
scopesarray<string>NoUser's permission scopes
forcePasswordChangebooleanNo
nationalitystringNoISO 3166-1 alpha-2 nationality code (e.g. "VN", "US")

Responses

201User created successfully | application/json | ApiResponse_UserResponse_
400Invalid request | application/json | ApiResponse_null_
401Unauthorized | application/json | ApiResponse_null_
409User already exists | application/json | ApiResponse_null_
Example 201 response
{
  "data": {
    "id": "123",
    "email": "user@example.com",
    "name": "John Doe",
    "telephoneNumber": "+1234567890",
    "isActive": true,
    "createdAt": "2026-04-07T15:56:49.865Z",
    "updatedAt": "2026-04-07T15:56:49.865Z",
    "nationality": "UK"
  }
}
GET /v1/users/me Get current user Users

Get the current user's details

Auth: jwt

Responses

200Success | application/json | ApiResponse_UserResponse_
401Unauthorized | application/json | ApiResponse_null_
404User not found | application/json | ApiResponse_null_
Example 200 response
{
  "data": {
    "id": "123",
    "email": "user@example.com",
    "name": "John Doe",
    "telephoneNumber": "+1234567890",
    "isActive": true,
    "createdAt": "2026-04-07T15:56:49.857Z",
    "updatedAt": "2026-04-07T15:56:49.857Z",
    "verified": false,
    "nationality": "UK"
  }
}
PATCH /v1/users/me/change-password ChangePassword Users
Auth: jwt (scopes: lawtech-admin, company-admin, company, company-user)Body: application/jsonParams: 1

Parameters

x-company-id (header)string, required

Request Body

Content-Typeapplication/json
SchemaChangePasswordRequest
RequiredYes
Fields
FieldTypeRequiredDescription
passwordstringYesThe user's password
emailstringYes
newPasswordstringYes
captchaTokenstringYes

Responses

200User updated successfully | application/json | ApiResponse_UserResponse_
400Invalid request | application/json | ApiResponse_null_
401Unauthorized | application/json | ApiResponse_null_
404User not found | application/json | ApiResponse_null_
Example 200 response
{
  "data": {
    "id": "123",
    "email": "user@example.com",
    "name": "Updated Name",
    "telephoneNumber": "+1234567890",
    "isActive": true,
    "createdAt": "2026-04-07T15:56:49.866Z",
    "updatedAt": "2026-04-07T15:56:49.866Z",
    "nationality": "UK"
  }
}
GET /v1/users/me/companies Get current user details and companies Users

Get the current user's details and associated companies

Auth: jwt

Responses

200Success | application/json | ApiResponse__user-UserResponse--companies-UserCompanyResponse-Array__
401Unauthorized | application/json | ApiResponse_null_
404User not found | application/json | ApiResponse_null_
Example 200 response
{
  "data": {
    "user": {
      "id": "123",
      "email": "user@example.com",
      "name": "John Doe",
      "telephoneNumber": "+1234567890",
      "isActive": true,
      "createdAt": "2026-04-07T15:56:49.858Z",
      "updatedAt": "2026-04-07T15:56:49.858Z",
      "nationality": "UK",
      "transactionID": "975873900988",
      "transactionExpiresAt": "2026-04-07T15:56:49.858Z",
      "isGrantAccess": true
    },
    "companies": [
      {
        "id": "company123",
        "name": "Example Company",
        "scopes": [
          "lawtech-admin"
        ]
      }
    ]
  }
}
GET /v1/users/me/documents Get current user documents Users

Get the current user's documents

Auth: jwt

Responses

200Success | application/json | ApiResponse_UserWithDocumentsResponse_
401Unauthorized | application/json | ApiResponse_null_
404User not found | application/json | ApiResponse_null_
Example 200 response
{
  "data": {
    "id": "123",
    "email": "user@example.com",
    "name": "John Doe",
    "telephoneNumber": "+1234567890",
    "isActive": true,
    "createdAt": "2026-04-07T15:56:49.859Z",
    "updatedAt": "2026-04-07T15:56:49.859Z",
    "documents": [
      {
        "id": "doc123",
        "name": "Example Document",
        "status": "draft",
        "createdAt": "2026-04-07T15:56:49.859Z"
      }
    ]
  }
}
GET /v1/users/me/documents/signer Get current user signer documents Users

Get the current user's documents where they are a signer

Auth: jwtParams: 4

Parameters

type (query)StatusSignerEnum — Optional status type filter. If not provided, returns all documents.
search (query)string — Optional search term to filter documents by name
page (query)number (double) — The page number for pagination (default: 1)
limit (query)number (double) — The number of items per page (default: 10)

Responses

200Success | application/json | PaginatedResponse_AdditionSigner-Array_
401Unauthorized | application/json | ApiResponse_null_
404User not found | application/json | ApiResponse_null_
Example 200 response
{
  "data": [
    {
      "document": {
        "companyId": "company123",
        "description": "Example document",
        "id": "doc123",
        "name": "Example Document",
        "status": "draft",
        "templateId": "template123",
        "type": "Standard",
        "signingUrl": "https://example.com/sign/123",
        "user": {
          "email": "user@example.com",
          "id": "user123",
          "isActive": true,
          "name": "John Doe",
          "telephoneNumber": "+1234567890",
          "nationality": "UK"
        }
      }
    }
  ],
  "metadata": {
    "total": 100,
    "page": 1,
    "limit": 10,
    "totalPages": 10,
    "timestamp": "2026-04-07T15:56:49.860Z"
  }
}
PATCH /v1/users/me/pin Change PIN Users

Change the current user's existing Personal Identification Code (PIN).

Auth: jwt (scopes: company-signer)Body: application/json

Request Body

Content-Typeapplication/json
SchemaUpdatePinRequest
RequiredYes
Fields
FieldTypeRequiredDescription
pinstringYesThe new PIN (6 digits) Pattern: ^\d{6}$ Example: 654321
currentPinstringYesRequired to verify identity before changing the PIN

Responses

200PIN updated successfully | application/json | ApiResponse__message-string__
400Validation error | application/json | ApiResponse_null_
401Unauthorized or incorrect current PIN | application/json | ApiResponse_null_
Example 200 response
{
  "data": {
    "message": "PIN updated successfully"
  }
}
POST /v1/users/me/pin Setup PIN (first-time) Users

Set up the current user's Personal Identification Code (PIN).

Auth: jwt (scopes: company-signer)Body: application/json

Request Body

Content-Typeapplication/json
SchemaSetupPinRequest
RequiredYes
Fields
FieldTypeRequiredDescription
pinstringYesUser's PIN/Passcode (6 digits) Pattern: ^\d{6}$ Example: 123456

Responses

200PIN set up successfully | application/json | ApiResponse__message-string__
400Validation error or PIN already exists | application/json | ApiResponse_null_
401Unauthorized | application/json | ApiResponse_null_
Example 200 response
{
  "data": {
    "message": "PIN set up successfully"
  }
}
POST /v1/users/me/pin/verify Verify PIN → token Users

Verify the current user's PIN and receive an access token

Auth: PublicBody: application/json

Request Body

Content-Typeapplication/json
SchemaVerifyPinRequest
RequiredYes
Fields
FieldTypeRequiredDescription
emailstringYesUser's email address
pinstringYesUser's PIN/Passcode (6 digits) Pattern: ^\d{6}$ Example: 123456

Responses

200PIN verified, token issued | application/json | ApiResponse_PinTokenResponse_
401Invalid PIN or PIN locked | application/json | ApiResponse_null_
404No PIN configured | application/json | ApiResponse_null_
Example 200 response
{
  "data": {
    "access_token": "<jwt>",
    "token_type": "Bearer",
    "expires_in": 86400
  }
}
PATCH /v1/users/me/va-pin Update Verification Data Users

Update the user's verification data (va_data, securityContext).

Auth: jwt (scopes: company-signer)Body: application/json

Request Body

Content-Typeapplication/json
SchemaUpdateVaPinRequest
RequiredYes
Fields
FieldTypeRequiredDescription
va_datastringNoFull verification payload (stored as jsonb string)
securityContextstringNoClient-provided security context
isGrantAccessbooleanNoWhether access is granted

Responses

200Verification PIN updated successfully | application/json | ApiResponse__message-string__
401Unauthorized or incorrect password | application/json | ApiResponse_null_
Example 200 response
{
  "data": {
    "message": "Verification PIN updated successfully"
  }
}
DELETE /v1/users/{id} Delete user Users

Delete a user

Auth: jwt (scopes: lawtech-admin, company-admin)Params: 3

Parameters

x-company-id (header)string, required — The company ID from x-company-id header
id (path)string, required — The unique identifier of the user to delete
deleteType (query)string — The type of delete operation (soft or hard)

Responses

200User deleted successfully | application/json | ApiResponse__message-string--success-boolean__
401Unauthorized | application/json | ApiResponse_null_
404User not found | application/json | ApiResponse_null_
Example 200 response
{
  "data": {
    "message": "User deleted successfully",
    "success": true
  }
}
GET /v1/users/{id} Get user details Users

Get a user by ID

Auth: jwt (scopes: lawtech-admin, company-admin)Params: 2

Parameters

x-company-id (header)string, required — The company ID from x-company-id header
id (path)string, required — The unique identifier of the user

Responses

200User retrieved successfully | application/json | ApiResponse_UserResponse_
400Company ID is required | application/json | ApiResponse__code-string--message-string__
401Unauthorized | application/json | ApiResponse__code-string--message-string__
404Not Found | application/json | ApiResponse__code-string--message-string__
Example 200 response
{
  "data": {
    "id": "123",
    "email": "user@example.com",
    "name": "John Doe",
    "telephoneNumber": "+1234567890",
    "isActive": true,
    "createdAt": "2026-04-07T15:56:49.864Z",
    "updatedAt": "2026-04-07T15:56:49.864Z",
    "nationality": "UK"
  }
}
PATCH /v1/users/{id} UpdateCompanyUser Users
Auth: jwt (scopes: lawtech-admin, company-admin, company)Body: application/jsonParams: 2

Parameters

x-company-id (header)string, required
id (path)string, required

Request Body

Content-Typeapplication/json
SchemaUpdateUserRequest
RequiredYes
Fields
FieldTypeRequiredDescription
namestringNoThe user's full name
passwordstringNoThe user's password
telephoneNumberstringNoThe user's telephone number
forcePasswordChangebooleanNo
emailstringNo
nationalitystringNoISO 3166-1 alpha-2 nationality code (e.g. "VN", "US")
securityContextstringNoClient-provided security context

Responses

200User updated successfully | application/json | ApiResponse_UserResponse_
400Invalid request | application/json | ApiResponse_null_
401Unauthorized | application/json | ApiResponse_null_
404User not found | application/json | ApiResponse_null_
Example 200 response
{
  "data": {
    "id": "123",
    "email": "user@example.com",
    "name": "Updated Name",
    "telephoneNumber": "+1234567890",
    "isActive": true,
    "createdAt": "2026-04-07T15:56:49.866Z",
    "updatedAt": "2026-04-07T15:56:49.866Z",
    "nationality": "UK"
  }
}
GET /v1/users/{id}/company Get user company Users

Get the company associated with a user for the specified company ID

Auth: jwt (scopes: lawtech-admin, company-admin, company, company-user)Params: 2

Parameters

x-company-id (header)string, required — The company ID from x-company-id header
id (path)string, required — The unique identifier of the user

Responses

200Success | application/json | ApiResponse_UserCompanyResponse_
401Unauthorized | application/json | ApiResponse_null_
404User or company not found | application/json | ApiResponse_null_
Example 200 response
{
  "data": {
    "id": "company123",
    "name": "Example Company",
    "scopes": [
      "company-admin"
    ]
  }
}
GET /v1/users/{id}/documents Get user documents Users

Get a user's documents

Auth: jwt (scopes: lawtech-admin, company-admin, company)Params: 2

Parameters

x-company-id (header)string, required — The company ID from x-company-id header
id (path)string, required — The unique identifier of the user

Responses

200User documents retrieved successfully | application/json | ApiResponse_UserWithDocumentsResponse_
400Company ID is required | application/json | ApiResponse__code-string--message-string__
401Unauthorized | application/json | ApiResponse__code-string--message-string__
404Not Found | application/json | ApiResponse__code-string--message-string__
Example 200 response
{
  "data": {
    "id": "123",
    "email": "user@example.com",
    "name": "John Doe",
    "telephoneNumber": "+1234567890",
    "isActive": true,
    "createdAt": "2026-04-07T15:56:49.864Z",
    "updatedAt": "2026-04-07T15:56:49.864Z",
    "nationality": "UK",
    "documents": [
      {
        "id": "doc123",
        "name": "Example Document",
        "status": "draft",
        "createdAt": "2026-04-07T15:56:49.864Z"
      }
    ]
  }
}

Company

8 endpoints

GET /v1/company Get current company Company

Get the current user's company information

Auth: jwt (scopes: lawtech-admin, company-admin, company-user, company)Params: 1

Parameters

x-company-id (header)string, required — The company ID from x-company-id header

Responses

200Success | application/json | ApiResponse_CompanyResponse_
401Unauthorized | application/json | ApiResponse_null_
404Company not found | application/json | ApiResponse_null_
Example 200 response
{
  "data": {
    "id": "company-123",
    "name": "Example Company Ltd",
    "isActive": true,
    "createdAt": "2026-04-07T15:56:49.996Z",
    "updatedAt": "2026-04-07T15:56:49.996Z"
  },
  "metadata": {
    "timestamp": "2026-04-07T15:56:49.996Z"
  }
}
PATCH /v1/company Update current company Company

Update the current company

Auth: jwt (scopes: lawtech-admin, company-admin, company)Body: application/jsonParams: 1

Parameters

x-company-id (header)string, required — The company ID from x-company-id header

Request Body

Content-Typeapplication/json
SchemaUpdateCompanyRequest
RequiredYes
Fields
FieldTypeRequiredDescription
namestringNoThe name of the company
webhookUrlstringNoThe webhook URL for receiving notifications

Responses

200Company updated successfully | application/json | ApiResponse_CompanyResponse_
400Invalid request | application/json | ApiResponse_null_
401Unauthorized | application/json | ApiResponse_null_
404Company not found | application/json | ApiResponse_null_
Example 200 response
{
  "data": {
    "id": "company-123",
    "name": "Updated Company Name",
    "webhookUrl": "https://example.com/webhook",
    "createdAt": "2026-04-07T15:56:49.996Z",
    "updatedAt": "2026-04-07T15:56:49.996Z",
    "isActive": true
  },
  "metadata": {
    "timestamp": "2026-04-07T15:56:49.996Z"
  }
}
DELETE /v1/company/client-secrets Delete client credentials Company

Delete the company's client credentials

Auth: jwt (scopes: lawtech-admin, company-admin, company)Params: 1

Parameters

x-company-id (header)string, required — The company ID from x-company-id header

Responses

201Client ID delete successfully | application/json
400Invalid request | application/json | ApiResponse_null_
401Unauthorized | application/json | ApiResponse_null_
Example 201 response
{
  "data": {
    "clientId": "string",
    "clientSecret": "clientId",
    "companyId": "clientId",
    "webhookSecret": "clientId"
  }
}
GET /v1/company/client-secrets Get client credentials Company

Get the company's client credentials

Auth: jwt (scopes: lawtech-admin, company-admin, company)Params: 1

Parameters

x-company-id (header)string, required — The company ID from x-company-id header

Responses

200Success | application/json | ApiResponse_CompanyClientID_
401Unauthorized | application/json | ApiResponse_null_
404Company not found | application/json | ApiResponse_null_
Example 200 response
{
  "data": {
    "clientId": "client-123",
    "clientSecret": "secret-456",
    "webhookSecret": "webhook-secret-789",
    "companyId": "company-123"
  },
  "metadata": {
    "timestamp": "2026-04-07T15:56:49.999Z"
  }
}
POST /v1/company/client-secrets create client credentials Company

Create the company's client credentials

Auth: jwt (scopes: lawtech-admin, company-admin, company)Params: 1

Parameters

x-company-id (header)string, required — The company ID from x-company-id header

Responses

201Client ID created successfully | application/json | ApiResponse_CompanyClientID_
400Invalid request | application/json | ApiResponse_null_
401Unauthorized | application/json | ApiResponse_null_
Example 201 response
{
  "data": {
    "clientId": "string",
    "clientSecret": "clientId",
    "companyId": "clientId",
    "webhookSecret": "clientId"
  }
}
GET /v1/company/stats Get company statistics Company

Get company statistics

Auth: jwt (scopes: lawtech-admin, company-admin, company-user, company)Params: 1

Parameters

x-company-id (header)string, required — The company ID from x-company-id header

Responses

200Success | application/json | ApiResponse_CompanyStatsView_
401Unauthorized | application/json | ApiResponse_null_
404Company not found | application/json | ApiResponse_null_
Example 200 response
{
  "data": {
    "totalUsers": 10,
    "roles": {
      "lawtechAdmin": 1,
      "companyAdmin": 2,
      "companyUser": 5,
      "companySigner": 2
    },
    "documents": {
      "awaitingUs": 5,
      "awaitingOthers": 3,
      "completed": 10,
      "terminated": 2,
      "needsAttention": 1,
      "declined": 1,
      "expired": 1,
      "revoked": 1,
      "draft": 2,
      "scheduled": 1,
      "total": 20
    }
  },
  "metadata": {
    "timestamp": "2026-04-07T15:56:49.997Z"
  }
}
GET /v1/company/users Get company users Company

Get all users associated with the current company

Auth: jwt (scopes: lawtech-admin, company-admin, company-user, company)Params: 3

Parameters

x-company-id (header)string, required — The company ID from x-company-id header
page (query)number (double) — The page number for pagination (default: 1)
limit (query)number (double) — The number of items per page (default: 10)

Responses

200Success | application/json | PaginatedResponse_Array__id-string--email-string--name-string--scopes-string-Array___
401Unauthorized | application/json | ApiResponse_null_
404Company not found | application/json | ApiResponse_null_
Example 200 response
{
  "data": [
    {
      "id": "user-123",
      "email": "john.doe@example.com",
      "name": "John Doe",
      "scopes": [
        "company-admin"
      ]
    },
    {
      "id": "user-124",
      "email": "jane.smith@example.com",
      "name": "Jane Smith",
      "scopes": [
        "company-user"
      ]
    }
  ],
  "metadata": {
    "total": 2,
    "page": 1,
    "limit": 10,
    "totalPages": 1,
    "timestamp": "2026-04-07T15:56:49.998Z"
  }
}

Companies

8 endpoints

GET /v1/companies Get all companies Companies

Get all companies

Auth: jwt (scopes: lawtech-admin)Params: 2

Parameters

page (query)number (double) — The page number for pagination (default: 1)
limit (query)number (double) — The number of items per page (default: 10)

Responses

200Success | application/json | PaginatedResponse_CompanyResponse-Array_
401Unauthorized | application/json | ApiResponse_null_
Example 200 response
{
  "data": [
    {
      "id": "123",
      "name": "Example Company",
      "isActive": true,
      "createdAt": "2026-04-07T15:56:50.007Z",
      "updatedAt": "2026-04-07T15:56:50.007Z"
    }
  ],
  "metadata": {
    "total": 100,
    "page": 1,
    "limit": 10,
    "totalPages": 10,
    "timestamp": "2026-04-07T15:56:50.007Z"
  }
}
POST /v1/companies Create company Companies

Create a new company

Auth: jwt (scopes: lawtech-admin)Body: application/jsonParams: 1

Parameters

x-company-id (header)string, required — The company ID from x-company-id header

Request Body

Content-Typeapplication/json
SchemaCreateCompanyRequest
RequiredYes
Fields
FieldTypeRequiredDescription
namestringYesThe name of the company
webhookUrlstringNoThe webhook URL for receiving notifications

Responses

201Company created successfully | application/json | ApiResponse_CompanyResponse_
400Invalid request | application/json | ApiResponse_null_
401Unauthorized | application/json | ApiResponse_null_
409Company already exists | application/json | ApiResponse_null_
Example 201 response
{
  "data": {
    "id": "company123",
    "name": "Example Company",
    "webhookUrl": "https://example.com/webhook",
    "createdAt": "2026-04-07T15:56:50.008Z",
    "updatedAt": "2026-04-07T15:56:50.008Z",
    "isActive": true
  }
}
DELETE /v1/companies/{id} Delete company Companies

Delete a company

Auth: jwt (scopes: lawtech-admin)Params: 3

Parameters

x-company-id (header)string, required — The company ID from x-company-id header
id (path)string, required — The unique identifier of the company to delete
deleteType (query)string — The type of delete operation (soft or hard)

Responses

200Company deleted successfully | application/json | ApiResponse__success-boolean__
401Unauthorized | application/json | ApiResponse_null_
404Company not found | application/json | ApiResponse_null_
Example 200 response
{
  "data": {
    "success": true
  }
}
GET /v1/companies/{id} Get company details Companies

Get detailed information about a specific company

Auth: jwt (scopes: lawtech-admin)Params: 2

Parameters

x-company-id (header)string, required — The company ID from x-company-id header
id (path)string, required — The unique identifier of the company

Responses

200Success | application/json | ApiResponse_CompanyResponse_
401Unauthorized | application/json | ApiResponse_null_
404Company not found | application/json | ApiResponse_null_
Example 200 response
{
  "data": {
    "id": "company123",
    "name": "Example Company",
    "createdAt": "2026-04-07T15:56:50.007Z",
    "updatedAt": "2026-04-07T15:56:50.007Z",
    "isActive": true
  }
}
PATCH /v1/companies/{id} Update company Companies

Update an existing company

Auth: jwt (scopes: lawtech-admin)Body: application/jsonParams: 2

Parameters

x-company-id (header)string, required — The company ID from x-company-id header
id (path)string, required — The unique identifier of the company to update

Request Body

Content-Typeapplication/json
SchemaUpdateCompanyRequest
RequiredYes
Fields
FieldTypeRequiredDescription
namestringNoThe name of the company
webhookUrlstringNoThe webhook URL for receiving notifications

Responses

200Company updated successfully | application/json | ApiResponse_CompanyResponse_
400Invalid request | application/json | ApiResponse_null_
401Unauthorized | application/json | ApiResponse_null_
404Company not found | application/json | ApiResponse_null_
Example 200 response
{
  "data": {
    "id": "company123",
    "name": "Updated Company Name",
    "webhookUrl": "https://example.com/webhook",
    "createdAt": "2026-04-07T15:56:50.008Z",
    "updatedAt": "2026-04-07T15:56:50.008Z",
    "isActive": true
  }
}
GET /v1/companies/{id}/client-secrets Get client credentials Companies

Get a company's client credentials

Auth: jwt (scopes: lawtech-admin)Params: 2

Parameters

x-company-id (header)string, required — The company ID from x-company-id header
id (path)string, required — The unique identifier of the company

Responses

200Success | application/json | ApiResponse__clientId-string--clientSecret-string--webhookSecret-string--companyId-string__
401Unauthorized | application/json | ApiResponse_null_
404Company not found | application/json | ApiResponse_null_
Example 200 response
{
  "data": {
    "clientId": "client123",
    "clientSecret": "new-secret-key",
    "webhookSecret": "new-webhook-secret",
    "companyId": "company123"
  }
}
GET /v1/companies/{id}/users Get company users Companies

Get all users associated with a company

Auth: jwt (scopes: lawtech-admin)Params: 4

Parameters

x-company-id (header)string, required — The company ID from x-company-id header
id (path)string, required — The unique identifier of the company
page (query)number (double) — The page number for pagination (default: 1)
limit (query)number (double) — The number of items per page (default: 10)

Responses

200Success | application/json | PaginatedResponse_Array__id-string--email-string--name-string--scopes-string-Array___
401Unauthorized | application/json | ApiResponse_null_
404Company not found | application/json | ApiResponse_null_
Example 200 response
{
  "data": [
    {
      "id": "user123",
      "email": "user@example.com",
      "name": "John Doe",
      "scopes": [
        "company-admin"
      ]
    }
  ],
  "metadata": {
    "total": 1,
    "page": 1,
    "limit": 10,
    "totalPages": 1,
    "timestamp": "2026-04-07T15:56:50.010Z"
  }
}

Documents

8 endpoints

GET /v1/documents Get all documents for a company Documents

Retrieve all documents

Auth: jwt (scopes: lawtech-admin, company-admin, company-user, company)Params: 6

Parameters

x-company-id (header)string, required — The company ID from x-company-id header
page (query)number (double) — The page number (default: 1)
limit (query)number (double) — The number of items per page (default: 10)
status (query)string — Optional document status filter Waiting For Me, Waiting For Others, Needs Attention, Completed, Declined, Expired, Revoked, Draft, Scheduled, Terminated
equal (query)boolean — Whether to return documents matching the status (true) or not matching the status (false). Defaults to true.
userId (query)string — Optional user ID to filter by

Responses

200Documents retrieved successfully | application/json | PaginatedResponse_DocumentWithSignersResponse-Array_
400Company ID is required | application/json | ApiResponse__code-string--message-string__
401Unauthorized | application/json | ApiResponse__code-string--message-string__
500Server error | application/json | ApiResponse__code-string--message-string__
Example 200 response
{
  "data": [
    {
      "id": "23f3ed80-7688-4152-91ff-b74fda59bd57",
      "name": "Contract Agreement",
      "description": "Please review and sign",
      "type": "Standard",
      "companyId": "company-123",
      "status": "Waiting For Me",
      "createdAt": "2026-04-07T15:56:49.989Z",
      "updatedAt": "2026-04-07T15:56:49.989Z",
      "signers": [
        {
          "id": "1624b7d5-1b96-436d-a576-7c64735a045d",
          "name": "John Doe",
          "email": "john@example.com",
          "status": "Completed",
          "signedAt": "2026-04-07T15:56:49.989Z",
          "updatedAt": "2026-04-07T15:56:49.989Z",
          "order": 1,
          "signerType": "Signer"
        }
      ]
    }
  ],
  "metadata": {
    "total": 100,
    "page": 1,
    "limit": 10,
    "totalPages": 10,
    "timestamp": "2026-04-07T15:56:49.989Z"
  }
}
POST /v1/documents Create document Documents

Create a new document

Auth: jwt (scopes: lawtech-admin, company-admin, company-user, company)Body: multipart/form-dataParams: 1

Parameters

x-company-id (header)string, required — The company ID from x-company-id header

Request Body

Content-Typemultipart/form-data
SchemaCreateDocumentRequest
RequiredYes
Fields
FieldTypeRequiredDescription
titlestringYesDocument title.
messagestringNoOptional message for signers.
typeStandard | Advanced | QualifiedYesDocument type.
documentSourceUpload | TemplateNoUpload (default) or Template.
templateIduuidNoRequired when documentSource=Template.
typeRecipientID_DOCUMENT | PASSPORT_ONLY | NORMALNoRecipient type configuration.
enableSigningOrderbooleanNoEnable signing order.
cc[].emailAddressstringNoCC recipient email.
signers[].namestringYesSigner name.
signers[].emailAddressstringNoSigner email.
signers[].signerOrdernumberNoSigning order number.
signers[].signerTypeSigner | Reviewer | InPersonSignerNoSigner type.
signers[].signerRolestringNoSigner role label.
signers[].deliveryModeEmail | SMS | EmailAndSMS | WhatsAppNoDelivery channel.
signers[].authenticationTypeAuthenticationTypeEnumNoAuthentication type.
signers[].enableEmailOTPbooleanNoEnable email OTP.
signers[].phoneNumberstringNoSigner phone number.
signers[].nationalitystringNoISO 2-character nationality.
signers[].signatureCoordinates.xPositionnumberNoX position.
signers[].signatureCoordinates.yPositionnumberNoY position.
signers[].signatureCoordinates.widthnumberNoWidth.
signers[].signatureCoordinates.heightnumberNoHeight.
signers[].signatureCoordinates.pageNumbernumberNoPage number.
files[]fileNoRequired when documentSource=Upload.

When documentSource=Upload, attach files[] (PDF). When documentSource=Template, pass templateId instead.

Responses

201Document created successfully | application/json | ApiResponse_DocumentResponse_
400Company ID is required | application/json | ApiResponse__code-string--message-string__
401Unauthorized | application/json | ApiResponse__code-string--message-string__
500Server error | application/json | ApiResponse__code-string--message-string__
Example 201 response
{
  "data": {
    "id": "doc-123",
    "name": "Contract Agreement",
    "description": "Please review and sign",
    "companyId": "company-123",
    "company": {
      "id": "company-123",
      "name": "Example Company",
      "createdAt": "2026-04-07T15:56:49.994Z",
      "updatedAt": "2026-04-07T15:56:49.994Z",
      "isActive": true
    },
    "createdAt": "2026-04-07T15:56:49.994Z",
    "updatedAt": "2026-04-07T15:56:49.994Z",
    "type": "Standard",
    "typeRecipient": "ID_DOCUMENT",
    "status": "Draft",
    "signers": [
      {
        "id": "signer-1",
        "name": "John Doe",
        "email": "john@example.com",
        "status": "Pending",
        "order": 1,
        "signerType": "Signer",
        "signerRole": "Primary Signer",
        "phoneNumber": "+1234567890",
        "nationality": "UK"
      },
      {
        "id": "signer-2",
        "name": "Jane Smith",
        "email": "jane@example.com",
        "status": "Pending",
        "order": 2,
        "signerType": "Signer",
        "signerRole": "Secondary Signer",
        "phoneNumber": "+0987654321",
        "nationality": "GB"
      }
    ]
  },
  "metadata": {
    "timestamp": "2026-04-07T15:56:49.994Z"
  }
}
GET /v1/documents/stats Get document statistics Documents

Get document statistics for both company and individual user

Auth: jwt (scopes: lawtech-admin, company-admin, company-user)Params: 1

Parameters

x-company-id (header)string, required — The company ID from x-company-id header

Responses

200Ok | application/json | ApiResponse_CompanyDocumentStatsResponse_
400Invalid request | application/json | ApiResponse__code-string--message-string__
401Unauthorized | application/json | ApiResponse__code-string--message-string__
500Internal server error | application/json | ApiResponse__code-string--message-string__
Example 200 response
{
  "data": {
    "company": {
      "awaitingUs": 5,
      "awaitingOthers": 3,
      "completed": 10,
      "terminated": 2,
      "needsAttention": 1,
      "declined": 1,
      "expired": 1,
      "revoked": 1,
      "draft": 2,
      "scheduled": 1,
      "total": 20
    },
    "user": {
      "awaitingMe": 2,
      "awaitingOthers": 3,
      "completed": 5,
      "terminated": 1,
      "needsAttention": 1,
      "declined": 1,
      "expired": 1,
      "revoked": 1,
      "draft": 2,
      "scheduled": 1,
      "total": 11
    }
  },
  "metadata": {
    "timestamp": "2026-04-07T15:56:49.990Z"
  }
}
GET /v1/documents/stats-month-status GetDocumentStatsMonthStatus Documents
Auth: jwt (scopes: lawtech-admin, company-admin, company-user)Params: 1

Parameters

x-company-id (header)string, required

Responses

200Ok | application/json | ApiResponse_DataCompanyDocumentStatsStatus-Array_
400Invalid request | application/json | ApiResponse__code-string--message-string__
401Unauthorized | application/json | ApiResponse__code-string--message-string__
500Internal server error | application/json | ApiResponse__code-string--message-string__
Example 200 response
{
  "data": [
    {
      "month": "Jan",
      "monthNumber": 0,
      "awaitingMe": 0,
      "awaitingOthers": 0,
      "needsAttention": 0,
      "revoked": 0,
      "signed": 0,
      "notSigned": 0,
      "total": 0
    }
  ],
  "metadata": {
    "timestamp": "2026-04-07T15:56:49.991Z"
  }
}
GET /v1/documents/{id} Get document details Documents

Get a document by ID

Auth: jwt (scopes: lawtech-admin, company-admin, company-user, company)Params: 2

Parameters

id (path)string, required — The unique identifier of the document
x-company-id (header)string, required — The company ID from x-company-id header

Responses

200Document retrieved successfully | application/json
400Company ID is required | application/json | ApiResponse__code-string--message-string__
401Unauthorized | application/json | ApiResponse__code-string--message-string__
404Document not found | application/json | ApiResponse__code-string--message-string__
500Server error | application/json | ApiResponse__code-string--message-string__
Example 200 response
{
  "data": {
    "id": "23f3ed80-7688-4152-91ff-b74fda59bd57",
    "name": "Contract Agreement",
    "description": "Please review and sign",
    "type": "Standard",
    "companyId": "company-123",
    "status": "Waiting For Me",
    "createdAt": "2026-04-07T15:56:49.991Z",
    "updatedAt": "2026-04-07T15:56:49.991Z",
    "signers": [
      {
        "id": "1624b7d5-1b96-436d-a576-7c64735a045d",
        "name": "John Doe",
        "email": "john@example.com",
        "status": "Completed",
        "signedAt": "2026-04-07T15:56:49.991Z",
        "updatedAt": "2026-04-07T15:56:49.991Z",
        "order": 1,
        "signerType": "Signer"
      }
    ]
  },
  "metadata": {
    "timestamp": "2026-04-07T15:56:49.991Z"
  }
}
PATCH /v1/documents/{id} Update document Documents

Update an existing document

Auth: jwt (scopes: lawtech-admin, company-admin, company-user, company)Body: application/jsonParams: 2

Parameters

x-company-id (header)string, required — The company ID from x-company-id header
id (path)string, required — The unique identifier of the document to update

Request Body

Content-Typeapplication/json
SchemaUpdateDocumentRequest
RequiredYes
Fields
FieldTypeRequiredDescription
namestringNo
descriptionstringNo
typeRecipientDocumentTypeRecipientsNoAllowed: ID_DOCUMENT, PASSPORT_ONLY, NORMAL

Responses

200Ok | application/json | ApiResponse_DocumentResponse_
400Company ID is required | application/json | ApiResponse__code-string--message-string__
401Unauthorized | application/json | ApiResponse__code-string--message-string__
GET /v1/documents/{id}/download Download document file Documents

Download a document file

Auth: jwt (scopes: lawtech-admin, company-admin, company-user, company)Params: 2

Parameters

id (path)string, required — The unique identifier of the document
x-company-id (header)string, required — The company ID from x-company-id header

Responses

200Ok | application/json
400Company ID is required | application/json | ApiResponse__code-string--message-string__
401Unauthorized | application/json | ApiResponse__code-string--message-string__
404Document not found | application/json | ApiResponse__code-string--message-string__
500Server error | application/json | ApiResponse__code-string--message-string__

Esign Templates

6 endpoints

GET /v1/esign-templates List Esign templates Esign Templates

List Esign template records for current user

Auth: jwtParams: 2

Parameters

page (query)number (double)
limit (query)number (double)

Responses

200Templates retrieved successfully | application/json | PaginatedResponse_BoldsignTemplateResponse-Array_
POST /v1/esign-templates Create Esign template record Esign Templates

Create a Esign template record

Auth: jwtBody: multipart/form-data

Request Body

Content-Typemultipart/form-data
SchemaCreateBoldsignTemplateRequest
RequiredYes
Fields
FieldTypeRequiredDescription
namestringYesTemplate name.
descriptionstringNoOptional description.
rolesarrayNoJSON array of roles (name, index, signerType).
roles[].namestringYesRole name.
roles[].indexnumberYesRole order (>=1).
roles[].signerTypestringNoSigner type label.
files[]fileYesTemplate PDF files.

The roles field can be JSON string or array.

Responses

201Template created successfully | application/json | ApiResponse_BoldsignTemplateResponse_
400Invalid request | application/json | ApiResponse__code-string--message-string__
Example 201 response
{
  "data": {
    "id": "template-uuid",
    "boldSignTemplateId": "boldsign-template-id",
    "name": "Employment Contract",
    "description": "Standard employment contract",
    "signersCount": 2,
    "roles": [
      {
        "name": "Employee",
        "signerType": "Signer",
        "index": 1
      },
      {
        "name": "Employer",
        "signerType": "Signer",
        "index": 2
      }
    ],
    "userId": "user-uuid",
    "errorMessage": null,
    "createUrl": "https://app.boldsign.com/embedded/...",
    "status": "completed",
    "files": [
      {
        "name": "employment-contract.pdf",
        "type": "application/pdf"
      }
    ],
    "createdAt": "2026-04-07T15:56:50.011Z",
    "updatedAt": "2026-04-07T15:56:50.011Z",
    "deletedAt": null
  }
}
DELETE /v1/esign-templates/{id} Soft delete Esign template Esign Templates

Soft delete Esign template record

Auth: jwtParams: 1

Parameters

id (path)string, required

Responses

200Template deleted successfully | application/json | ApiResponse_string_
404Template not found | application/json | ApiResponse__code-string--message-string__
GET /v1/esign-templates/{id} Get Esign template Esign Templates

Get Esign template record by ID

Auth: jwtParams: 1

Parameters

id (path)string, required

Responses

200Template retrieved successfully | application/json | ApiResponse_BoldsignTemplateResponse_
404Template not found | application/json | ApiResponse__code-string--message-string__
PATCH /v1/esign-templates/{id} Update Esign template Esign Templates

Update Esign template record

Auth: jwtBody: multipart/form-dataParams: 1

Parameters

id (path)string, required

Request Body

Content-Typemultipart/form-data
SchemaUpdateBoldsignTemplateRequest
Fields
FieldTypeRequiredDescription
namestringNoTemplate name.
descriptionstringNoOptional description.
rolesarrayNoJSON array of roles (name, index, signerType).
roles[].namestringNoRole name.
roles[].indexnumberNoRole order (>=1).
roles[].signerTypestringNoSigner type label.
files[]fileNoOptional updated PDF files.

The roles field can be JSON string or array.

Responses

200Template updated successfully | application/json | ApiResponse_BoldsignTemplateResponse_
404Template not found | application/json | ApiResponse__code-string--message-string__
GET /v1/esign-templates/{id}/embedded-edit-url Get embedded template edit URL Esign Templates

Get embedded template edit URL

Auth: jwtParams: 1

Parameters

id (path)string, required

Responses

200Edit URL generated successfully | application/json | ApiResponse_EmbeddedTemplateEditUrlResponse_
404Template not found | application/json | ApiResponse__code-string--message-string__
Example 200 response
{
  "data": {
    "editUrl": "https://app.boldsign.com/embedded/..."
  }
}

File-Service

2 endpoints

GET /v1/file-service/{documentId}/documents GetFileDocument File-Service
Auth: jwtParams: 2

Parameters

documentId (path)string, required
fileName (query)string

Responses

200File retrieved successfully | application/json
401Unauthorized | application/json | ApiResponse_null_
404File not found | application/json | ApiResponse_null_
Example 200 response
{
  "contentType": "application/pdf"
}
GET /v1/file-service/{key} Get file by key File-Service

Get a file by its key

Auth: jwtParams: 1

Parameters

key (path)string, required — The unique identifier of the file to retrieve

Responses

200File retrieved successfully | application/json
401Unauthorized | application/json | ApiResponse_null_
404File not found | application/json | ApiResponse_null_
Example 200 response
{
  "contentType": "application/pdf"
}

ID-Card

4 endpoints

GET /v1/users/me/id-cards Get ID card info ID-Card

Get ID card information

Auth: jwt

Responses

200ID card information retrieved successfully | application/json
400Invalid request | application/json | ApiResponse_ErrorResponse_
401Invalid credentials | application/json | ApiResponse_ErrorResponse_
404Not found data | application/json | ApiResponse_ErrorResponse_
500Server error | application/json | ApiResponse_ErrorResponse_
Example 200 response
{
  "data": {
    "id": "id-card-123",
    "createdAt": "2024-03-20T12:00:00.000Z",
    "updatedAt": "2024-03-20T12:00:00.000Z"
  }
}
POST /v1/users/me/id-cards Create ID card ID-Card

Create a new ID card

Auth: jwtBody: multipart/form-data

Request Body

Content-Typemultipart/form-data
SchemaCreateIdCardInput
RequiredYes
Fields
FieldTypeRequiredDescription
files[]fileYes1-3 images (JPG/PNG).
dateOfBirthstringNo
dateOfExpirystringNo
dateOfIssuestringNo
verificationDatestringNo
documentNumberstringNo
countrystringNo
givenNamesstringNo
mrzCodestringNo
namestringNo
nationalitystringNo
sexstringNo
surnamestringNo
placeOfBirthstringNo
portraitstringNo
signaturestringNo
faceImagestringNo
docFrontstringNo
documentNamestringNo
authoritystringNo
scorenumberNo
isFaceMatchbooleanNo
isDocumentValidbooleanNo
docTypestringNo
docBackstringNo
nfcImagestringNo
cardAccessNumberstringNo
faceLivenessstringNo
faceCompareScorenumberNo
nfcCheckbooleanNo
skipNfcReasonstringNo
issuingStateCodestringNo
documentClassCodestringNo

Supports up to 3 images. File size max 40MB.

Responses

201ID card created successfully | application/json | ApiResponse_Partial_IDCardResponse__
400Invalid request | application/json | ApiResponse_ErrorResponse_
401Invalid credentials | application/json | ApiResponse_ErrorResponse_
500Server error | application/json | ApiResponse_ErrorResponse_
Example 201 response
{
  "data": {
    "id": "id-card-123",
    "createdAt": "2024-03-20T12:00:00.000Z",
    "updatedAt": "2024-03-20T12:00:00.000Z"
  }
}
DELETE /v1/users/me/id-cards/{id} Delete ID card ID-Card

Delete an ID card

Auth: jwtParams: 1

Parameters

id (path)string, required — The ID of the ID card to delete

Responses

200ID card deleted successfully | application/json
400Invalid request | application/json | ApiResponse_ErrorResponse_
401Invalid credentials | application/json | ApiResponse_ErrorResponse_
404Not found data | application/json | ApiResponse_ErrorResponse_
500Server error | application/json | ApiResponse_ErrorResponse_
Example 200 response
{
  "data": {
    "data": "Delete id card success"
  }
}
PATCH /v1/users/me/id-cards/{id} Update ID card ID-Card

Update an existing ID card

Auth: jwtBody: multipart/form-dataParams: 1

Parameters

id (path)string, required — The ID of the ID card to update

Request Body

Content-Typemultipart/form-data
SchemaUpdateIdCardBody
Fields
FieldTypeRequiredDescription
files[]fileNoOptional replacement images.
dateOfBirthstringNo
dateOfExpirystringNo
dateOfIssuestringNo
verificationDatestringNo
documentNumberstringNo
countrystringNo
givenNamesstringNo
mrzCodestringNo
namestringNo
nationalitystringNo
sexstringNo
surnamestringNo
placeOfBirthstringNo
portraitstringNo
signaturestringNo
faceImagestringNo
docFrontstringNo
documentNamestringNo
authoritystringNo
scorenumberNo
isFaceMatchbooleanNo
isDocumentValidbooleanNo
docTypestringNo
docBackstringNo
nfcImagestringNo
cardAccessNumberstringNo
faceLivenessstringNo
faceCompareScorenumberNo
nfcCheckbooleanNo
skipNfcReasonstringNo
issuingStateCodestringNo
documentClassCodestringNo

Responses

200ID card updated successfully | application/json | ApiResponse_Partial_IDCardResponse__
400Invalid request | application/json | ApiResponse_ErrorResponse_
401Invalid credentials | application/json | ApiResponse_ErrorResponse_
404Not found data | application/json | ApiResponse_ErrorResponse_
500Server error | application/json | ApiResponse_ErrorResponse_
Example 200 response
{
  "data": {
    "id": "id-card-123",
    "createdAt": "2024-03-20T12:00:00.000Z",
    "updatedAt": "2024-03-20T12:00:00.000Z"
  }
}

ID Verification

3 endpoints

POST /v1/verification Verify user identity ID Verification

Verify user identity

Auth: jwt (scopes: lawtech-admin, company, company-admin)Body: application/jsonParams: 1

Parameters

x-company-id (header)string, required — The company ID from x-company-id header

Request Body

Content-Typeapplication/json
SchemaVerificationRequest
RequiredYes
Fields
FieldTypeRequiredDescription
emailstringYes
firstNamestringYes
lastNamestringYes
phoneNumberstringNo

Responses

200Verification successful | application/json | ApiResponse_VerificationResponse_
400Invalid request | application/json | ApiResponse_null_
401Unauthorized | application/json | ApiResponse_null_
404ID card not found | application/json | ApiResponse_null_
Example 200 response
{
  "data": {
    "id": "123",
    "decisionDate": "2026-04-07T15:56:49.869Z",
    "localName": "John Doe",
    "document": {
      "type": "Passport",
      "number": "P123456789",
      "validFrom": "2020-01-01T00:00:00.000Z",
      "validUntil": "2030-01-01T00:00:00.000Z",
      "firstName": "John",
      "lastName": "Doe",
      "gender": "Male",
      "citizenship": "Untied Kingdom",
      "dateOfBirth": "1990-01-01T00:00:00.000Z",
      "placeOfBirth": "London",
      "status": "verified"
    }
  },
  "metadata": {
    "timestamp": "2026-04-07T15:56:49.869Z"
  }
}
GET /v1/verification/{id} Get verification status ID Verification

Get verification status

Auth: jwt (scopes: lawtech-admin, company)Params: 2

Parameters

id (path)string, required — The verification ID
x-company-id (header)string, required — The company ID from x-company-id header

Responses

200Verification status retrieved successfully | application/json | ApiResponse_VerificationResponse_
401Unauthorized | application/json | ApiResponse_null_
404Verification not found | application/json | ApiResponse_null_
Example 200 response
{
  "data": {
    "id": "123",
    "decisionDate": "2026-04-07T15:56:49.870Z",
    "localName": "John Doe",
    "document": {
      "type": "Passport",
      "number": "P123456789",
      "validFrom": "2020-01-01T00:00:00.000Z",
      "validUntil": "2030-01-01T00:00:00.000Z",
      "firstName": "John",
      "lastName": "Doe",
      "gender": "Male",
      "citizenship": "United Kingdom",
      "dateOfBirth": "1990-01-01T00:00:00.000Z",
      "placeOfBirth": "London",
      "status": "verified"
    }
  },
  "metadata": {
    "timestamp": "2026-04-07T15:56:49.870Z"
  }
}
GET /v1/verification/{id}/download Download verification PDF ID Verification

Download verification PDF

Auth: jwt (scopes: lawtech-admin, company)Params: 2

Parameters

id (path)string, required — The verification ID
x-company-id (header)string, required — The company ID from x-company-id header

Responses

200PDF downloaded successfully | application/json
401Unauthorized | application/json | ApiResponse_null_
404Verification not found | application/json | ApiResponse_null_

Evrotrust

5 endpoints

GET /v1/evrotrust/callback Web SDK Callback Evrotrust

Handle Evrotrust Web SDK callback (via Redirect)

Auth: PublicParams: 5

Parameters

external_reference_id (query)string, required
reference_id (query)string
status (query)number (double), required
unsuccess_reason (query)string
error (query)string

Responses

200Callback processed successfully | application/json | ApiResponse__message-string__
POST /v1/evrotrust/document/doc/identification Fetch identification data Evrotrust

Get Evrotrust document identification data

Auth: jwtBody: application/json

Request Body

Content-Typeapplication/json
SchemaRecord_string.unknown_
RequiredYes

Responses

200Identification data retrieved successfully | application/json | ApiResponse_EvrotrustIdentificationResponse_
401Unauthorized | application/json | ApiResponse_null_
500Internal server error | application/json | ApiResponse_null_
Example 200 response
{
  "data": {
    "transactionID": "975873900988",
    "threadID": "432A97C5F068"
  }
}
POST /v1/evrotrust/document/download Download document content Evrotrust

Download Evrotrust document

Auth: jwtBody: application/json

Request Body

Content-Typeapplication/json
SchemaEvrotrustDocumentDownloadRequest
RequiredYes
Fields
FieldTypeRequiredDescription
transactionIDstringYes

Responses

200Document downloaded successfully | application/json
401Unauthorized | application/json | ApiResponse_null_
500Internal server error | application/json | ApiResponse_null_
POST /v1/evrotrust/document/status Fetch document status Evrotrust

Get Evrotrust document status

Auth: jwtBody: application/json

Request Body

Content-Typeapplication/json
SchemaEvrotrustDocumentStatusRequest
RequiredYes
Fields
FieldTypeRequiredDescription
transactionIDstringYes

Responses

200Document status retrieved successfully | application/json | ApiResponse_Record_string.unknown__
401Unauthorized | application/json | ApiResponse_null_
500Internal server error | application/json | ApiResponse_null_
Example 200 response
{
  "data": {
    "transactionID": "601071623405"
  }
}
POST /v1/evrotrust/session Create SDK session Evrotrust

Create an Evrotrust Web SDK session

Auth: jwtBody: application/json

Request Body

Content-Typeapplication/json
RequiredYes
Fields
FieldTypeRequiredDescription
emailstringYes
user_pidstringNo
user_countrystringNo
user_document_typenumberNoAllowed: 101, 201
redirect_urlstringNo
external_referencestringNo
colorDataEvrotrustColorDataNo
colorData.backgroundColorstringNo
colorData.borderColorstringNo
colorData.titleColorstringNo
colorData.subTitleColorstringNo
colorData.screenTextColorstringNo
colorData.buttonColorstringNo
colorData.buttonTextColorstringNo
colorData.iconsColorstringNo

Responses

200Session created successfully | application/json | ApiResponse_EvrotrustSessionResponse_
401Unauthorized | application/json | ApiResponse_null_
500Internal server error | application/json | ApiResponse_null_

Webhook

2 endpoints

POST /v1/webhook Process webhook events Webhook

Handle BoldSign webhook events

Auth: PublicBody: application/json

Request Body

Content-Typeapplication/json
SchemaWebhookData
RequiredYes
Fields
FieldTypeRequiredDescription
jsonRecord_string.unknown_NoConstruct a type with a set of properties K of type T
filesarray<object>No
files[].metadataRecord_string.unknown_NoConstruct a type with a set of properties K of type T
files[].sizenumber (double)No
files[].typestringYes
files[].contentstringYes
files[].namestringYes

Signed payload from BoldSign. Verify signature with x-webhook-signature header.

Responses

200Webhook processed successfully | application/json
400Bad Request - Invalid payload | application/json | ApiResponse_ErrorResponse_
401Unauthorized - Invalid signature | application/json | ApiResponse_ErrorResponse_
Example 200 response
{
  "data": [
    {
      "status": "signed",
      "signerEmail": "user@example.com"
    }
  ]
}
POST /v1/webhook/listener Listener webhook event Webhook

Listener webhook event

Auth: PublicBody: application/jsonParams: 2

Parameters

x-company-id (header)string, required — The company ID
x-webhook-signature (header)string, required — The webhook signature from x-webhook-signature header

Request Body

Content-Typeapplication/json
SchemaWebhookData
RequiredYes
Fields
FieldTypeRequiredDescription
jsonRecord_string.unknown_NoConstruct a type with a set of properties K of type T
filesarray<object>No
files[].metadataRecord_string.unknown_NoConstruct a type with a set of properties K of type T
files[].sizenumber (double)No
files[].typestringYes
files[].contentstringYes
files[].namestringYes

Listener endpoint for webhook events.

Responses

200Webhook event received | application/json | ApiResponse__status-string--event_63_-string--data_63_-WebhookData__
400Invalid webhook signature | application/json | ApiResponse_null_
401Unauthorized | application/json | ApiResponse_null_
403Forbidden | application/json | ApiResponse_null_
Example 200 response
{
  "data": {
    "status": "received",
    "event": "signed",
    "data": {
      "json": {
        "documentId": "123"
      },
      "files": [
        {
          "name": "document.pdf",
          "content": "base64content",
          "type": "application/pdf",
          "size": 1024,
          "metadata": {
            "pageCount": 5,
            "signedBy": "John Doe"
          }
        }
      ]
    }
  },
  "metadata": {
    "timestamp": "2026-04-07T15:56:49.830Z"
  }
}

Health

1 endpoints

GET /smoke Get application health status Health

Check application health and dependencies

Auth: Public

Responses

200Application is healthy | application/json | ApiResponse_SmokeResponse_
500Application is unhealthy | application/json | ApiResponse_ErrorResponse_
Example 200 response
{
  "data": {
    "buildId": "v1.0.0-20240320.1"
  }
}

Using the API

Error Handling

Standard HTTP errors with structured error payloads.

400 Bad Request

Missing required fields or invalid form-data.

401 Unauthorized

Invalid token or missing `Authorization` header.

403 Forbidden

Token lacks the required scopes for the endpoint.

500 Server Error

Unexpected exception. Provide `X-Request-ID` for support.

{
  "data": null,
  "error": {
    "code": "AUTH_401",
    "message": "Invalid access token",
    "details": {
      "field": "Authorization",
      "reason": "expired"
    }
  }
}