This page is meant for developers, vendors, and IT administrators to understand how to generate the bearer token to access our API to create/send and fetch status of letters.
Bearer authentication (also called token authentication) is an HTTP authentication scheme that involves security tokens called bearer tokens. LetterSG uses bearer authentication.
To generate the token, click on "API Integration" in the navigation bar. From there, click on Generate API key and copy the token. Use this key to start using LetterSG's API.
Authentication
LetterSG's API uses APIKey for authentication. User can view and manage API Keys in LetterSG API Dashboard.
Staging secret keys will have test_v1_version prefix.
Production secret keys will have live_v1_version prefix.
Authentication to the API is performed via bearer auth.
All API requests must be made over HTTPS. Calls made over plain HTTP will fail and requests without authentication will also fail.
To verify that your API key is working, send a curl request:
This request gets the template details for template 155, our sample template OGP - Certificate of Curiosity.
You should see a response containing the details for template 155:
{"templateId":155,"fields": ["recipient_name" ],"name":"OGP - Certificate of Curiosity","createdAt":"2023-11-09T04:17:49.631Z","updatedAt":"2023-11-09T04:17:50.000Z"}
Errors
LetterSG API uses conventional API Error to indicate the success or failure of an API request.
Rate Limits
For all of LetterSG's APIs, LetterSG allows up to 20 requests per second per user (subject to change).
Endpoints
Get All Templates
To see all templates that you have access to, send a GET request to list all templates. This endpoint also returns template fields that you will need to provide when generating the letters for each template.
GET/v1/templates
Request Query Parameters:
Returned object:
// list of all templates that the user has access to[ templates: { templateId: number fields: string[] name: string createdAt: string updatedAt: string }[], count: number]
Sample Request:
# replace live_v1_YOUR_API_KEY with your actual API keycurl--location \--request GET'https://letters.gov.sg/api/v1/templates?limit=2&offset=5' \--header 'Authorization: Bearer live_v1_YOUR_API_KEY'
Returns:
["templates": [ {"templateId":234,"fields": ["name","name_2"],"name":"Template Name 1","createdAt":"2022-09-19T03:31:00.131Z","updatedAt":"2022-09-19T03:31:00.131Z" }, {"templateId":45,"fields": ["name","name_2"],"name":"Template Name 2","createdAt":"2022-09-19T03:31:00.131Z","updatedAt":"2022-09-19T03:31:00.131Z" } ],"count": 40]
Get Template Details by ID
To see the details of a template, send a GET request with the template ID of the template. This endpoint returns the template fields you need to provide when generating a letter.
GET/v1/templates/:id
Request Query Parameters:
Returned object:
// details of template{ templateId: number fields: string[] name: string createdAt: string updatedAt: string}
Sample Request:
# replace live_v1_YOUR_API_KEY with your actual API keycurl--location \--request GET'https://letters.gov.sg/api/v1/templates/155' \--header 'Authorization: Bearer live_v1_YOUR_API_KEY'
Returns:
{"templateId":155,"fields": ["recipient_name" ],"name":"OGP - Certificate of Curiosity","createdAt":"2023-11-09T04:17:49.631Z","updatedAt":"2023-11-09T04:17:50.000Z"}
Create Letter
To create a new letter, send a POST request specifying the template you would like to use, and the provide the relevant template fields for the letter. If you are unsure which template fields are required for the template, see Get Template Details By Id.
The endpoint returns the link to the created letter, the public id of the letter, and the html of the created letter. If you need to query the status of the letter or retrieve information about the letter, please store the public id of the letter as this is the unique identifier for this letter.
POST/v1/letters
Request body:
Notification params, if provided, should look like so:
# replace live_v1_YOUR_API_KEY with your actual API key# sample request to create a letter only, without SMS or EMAIL notificationcurl--location'https://letters.gov.sg/api/v1/letters' \--header 'Content-Type: application/json' \--header 'Authorization: Bearer live_v1_YOUR_API_KEY' \--data '{ "templateId": 155, "letterParams": { "recipient_name": "Maxine Marcella" }}'# sample request with SMS notification# replace YOUR_PHONE_NUMBER_STARTING_WITH_8_OR_9 with your phone number# this sends a real SMS out, please test with your own phone numbercurl--location'https://letters.gov.sg/api/v1/letters' \--header 'Content-Type: application/json' \--header 'Authorization: Bearer live_v1_YOUR_API_KEY' \--data '{ "templateId": 155, "letterParams": { "recipient_name": "Maxine Marcella" }, "notificationParams": { "recipient": "YOUR_PHONE_NUMBER_STARTING_WITH_8_OR_9", "notificationMethod": "SMS" }}'# sample request with EMAIL notification# replace YOUR_EMAIL with your email address# this sends a real email out, please test with your own email addresscurl--location'https://letters.gov.sg/api/v1/letters' \--header 'Content-Type: application/json' \--header 'Authorization: Bearer live_v1_YOUR_API_KEY' \--data '{ "templateId": 155, "letterParams": { "recipient_name": "Maxine Marcella" }, "notificationParams": { "recipient": "YOUR_EMAIL", "notificationMethod": "EMAIL" }}'
{"statusCode":404,"message":"Template not found","error":"Not Found"}
// extra letter param in request, serial_number{"message":"Invalid letter params.","error": [ {"id":0,"param":"serial_number","message":"Invalid attribute in param","displayedErrorMessage":" is an extra field" } ]}// missing letter param in request, recipient_name{"message":"Invalid letter params.","error": [ {"id":0,"param":"recipient_name","message":"Missing param","displayedErrorMessage":" field is missing" } ]}
Get Letter Metadata
To retrieve the status of the letter, send a GET request with the public id of the letter that you would like to retrieve metadata for. You are only able to retrieve the metadata of letters that you have access to.
# replace live_v1_YOUR_API_KEY with your actual API keycurl--location \--request GET'https://letters.gov.sg/api/v1/letters/2here-8o5td-9g4b6-xfd86' \--header 'Authorization: Bearer live_v1_YOUR_API_KEY'
To download the issued letter as a PDF for archiving, send a GET request with the publicId of the letter.
Note: We may choose to further rate limit this endpoint in the future. This endpoint currently is offered in beta, and may not be always offered as a synchronous response.
GET/v1/letters/:publicId/pdfs
Request Query Parameters:
Returns:
Redirects to presigned URL link with a 1-hour expiry (returning a 302 status).
// url to download link{ presignedUrl: string}
Sample request:
# downloads PDF as 2here-8o5td-9g4b6-xfd86.pdf on your device# replace live_v1_YOUR_API_KEY with your actual API keycurl--location \--request GET'https://letters.gov.sg/api/v1/letters/2here-8o5td-9g4b6-xfd86/pdfs' \--header 'Authorization: Bearer live_v1_YOUR_API_KEY'--output2here-8o5td-9g4b6-xfd86.pdf
Keen on APIs?
For more information on integrating your systems with LetterSG, reach out to us at support@letters.gov.sg
Status Codes
Description
Environment
Endpoint
Parameter
Type
Default value
Required?
Parameter
Type
Default value
Required?
Property
Type
Required?
Property
Type
Required
Parameter
Type
Default value
Required?
Field Returned
What it means
Example
Parameter
Type
Default value
Required?
200 - OK
Everything worked as expected.
302 - Redirect
(PDF endpoint) Redirects to the presigned URL for PDF.
400 - Bad Request
The request was unacceptable, often due to missing a required parameter.
401 - Unauthorized
No valid API key provided.
402 - Request Failed
The parameters were valid but the request failed.
404 - Not Found
The requested resource doesn't exist.
429 - Too Many Requests
Too many requests hit the API too quickly. We recommend an exponential backoff of your requests.
500, 502, 503, 504 - Server Errors
Something went wrong on LetterSG's API end.
Production
https://letters.gov.sg/api/
Staging
https://staging.letters.gov.sg/api/
limit
number
100
No, optional
offset
number
0
No, optional
id
number
nil
Yes, required
templateId
number
Yes, required
letterParams
JSON
Yes, required
notificationParams
JSON
No, optional
recipient
string
Yes, required
notificationMethod
ENUM (either "SMS" or "EMAIL", these are case-sensitive)
Yes, required
publicId
string
nil
Yes, required
publicId
Letter ID for fetching the read status
xxyyy-12345-ddsss-d3454
letterLink
Original link of the letter
https://letters.gov.sg/letters/public-letter-id
createdAt
Timestamp of letter creation
2022-09-19T03:31:00.131Z
firstReadAt
(Optional) Timestamp of first read of letter, if letter is read
2022-09-19T03:31:00.131Z
notificationStatus
(Optional) Status of the notification that was sent, this could be "SENT", "FAILED", "INVALID_RECIPIENT", "PENDING"