About webhooks 🔗
You must be subscribed to the Autopilot or a higher tier to set up webhooks. Webhook configuration is also available in the Localazy web UI.
When the event occurs, all URLs with the given event configured are called with a POST
request. The header Content-Type
is set to application/json
and in the POST
body, a JSON
structure with additional information is provided. Timeouts are set to 10 seconds. Redirects are enabled.
Security 🔗
Localazy signs the webhook events it sends to your endpoints and adds a signature in the request header. This allows you to verify that the events were sent by Localazy and not a third party.
Header name | Description | Type |
---|---|---|
X-Localazy-Timestamp | UNIX timestamps in seconds | string |
X-Localazy-HMAC | HMAC SHA 256 of “{ts}-{raw post body}” signed by secret |
string |
How to verify webhook requests?
Before you can verify signatures, you need to retrieve your project secret using the webhook secret endoint.
To verify that the request sent is valid (and therefore has not been modified during the transfer) calculate the hash of the request, and compare it with the value stored in the X-Localazy-HMAC
header:
const crypto = require("crypto");
// `secret` fetched with the /projects/{projectId}/webhooks/secret endpoint
const secretHmac = crypto.createHmac("sha256", secret);
// `xLocalazyTimestamp`: X-Localazy-Timestamp header value
// `body` the webhook POST body
const signedMessage = secretHmac.update(`${xLocalazyTimestamp}-${JSON.stringify(body)}`).digest("hex");
// `xLocalazyHmac`: X-Localazy-HMAC header value
if (xLocalazyHmac !== signedMessage) {
// processing the request is not recommended, reqeuest has been modified
}
// request can be safely processed
List webhooks configuration 🔗
[GET] /projects/{projectId}/webhooks
Type | Value |
---|---|
Roles | reviewer |
Produces | application/json |
Returns the webhooks configuration for the given project.
Params
{projectId}
- Your project Id. Use the value from projects endpoint
Sample Request 🔗
curl --request GET \
--url https://api.localazy.com/projects/{projectId}/webhooks \
--header 'Authorization: Bearer {{token}}'
Sample Response 🔗
{
"items": [
{
"enabled": true,
"customId": "my-custom-id",
"description": "Inform backend that the project is published.",
"url": "https://webhook-target-url.com/webhook1",
"events": [
"project_published"
]
},
{
"enabled": false,
"customId": "",
"description": "",
"url": "https://webhook-target-url.com/webhook2",
"events": [
"project_published"
]
}
]
}
Response Object
Field | Description |
---|---|
enabled | Wheter the webhook is enabled or disabled. |
customId | Custom ID that is passed when the webhook is invoked. Empty by default. |
description | Description of the webhook. Empty by default. |
url | URL which is invoked on the webhook event. |
events | The list of event types for which this webhook is invoked. |
Update webhooks configuration 🔗
[POST] /projects/{projectId}/webhooks
Type | Value |
---|---|
Roles | reviewer |
Produces | application/json |
Consumes | application/json |
Store a new webhooks configuration for the project. You can use project’s id or slug as {projectId}.
Limits:
- There can be max. 30 webhooks per project.
- URL can be max. 1024 chars long.
- There can be max. of 50 events per webhook.
- Event can be max. 32 chars long.
Sample Request 🔗
curl --request POST \
--url https://api.localazy.com/projects/{projectId}/webhooks \
--header 'Authorization: Bearer {{token}}' \
--header 'Content-Type: application/json' \
--data '{
"items": [
{
"enabled": true,
"customId": "my-custom-id",
"description": "Inform backend that the project is published.",
"url": "https://webhook-target-url.com/webhook1",
"events": [
"project_published"
]
},
{
"enabled": false,
"customId": "",
"description": "",
"url": "https://webhook-target-url.com/webhook2",
"events": [
"project_published"
]
}
]
}'
Request Object
Field | Description |
---|---|
enabled |
Allows to enabled/disable the webhook. |
customId |
Custom ID that is passed when the webhook is invoked. Empty by default. |
description |
Description of the webhook. Empty by default. |
url |
URL to be invoked on the webhook event. |
events |
The list of event types to invoke this webhook for. |
Sample Response 🔗
{
"result": true
}
Field | Description |
---|---|
result | Success status of operation |
Event Types 🔗
List of events that can be triggered by the webhook. Can be one of [comment_added
, import_finished
, import_finished_empty
, project_published
, tag_promoted
].
Comment Added 🔗
- Idenfitier:
comment_added
- Triggered when a comment is added to the specified project
Request Body
{
"type": "comment_added",
"projectId": "_a8402929705887203313",
"customId": "",
"phraseId": "_a8402929700326342655",
"langId": 60,
"locale": "cs",
"text": "Text of the comment...",
"url": "https://localazy.com/p/test-project/phrases/60/edit/_a8402929700326342655",
"user": {
"id": "_a8402929715013877756",
"image": "",
"name": "John Doe",
"slug": "john-doe"
}
}
Field | Description |
---|---|
type |
Webhook event type |
projectId |
the Localazy project identifier |
customId |
the webhook identifier (empty when defined in UI, modifiable over Public API) |
phraseId |
the phrase identifier the comment belongs to |
langId |
the language identifier the comment belongs to |
locale |
the locale code the comment belongs to |
text |
the comment text |
url |
the comment URL |
user |
an object containing the basic commenting user information. See User Object below. |
User Object
Field | Description |
---|---|
id |
the user identifier |
image |
the user image |
name |
the user name |
slug |
the user slug |
Content Imported 🔗
- Identifier:
import_finished
- The webhook is invoked when importing is finished (from CLI or Gradle). Event
import_finished
is invoked only when there are added, updated or deprecated keys.
Request Body
{
"type": "import_finished",
"projectId": "_a8402929705887203313",
"customId": "",
"added": 5,
"updated": 1,
"deprecated": 3
}
Field | Description |
---|---|
type |
Webhook event type |
projectId |
the Localazy project identifier |
customId |
the webhook identifier (empty when defined in UI, modifiable over Public API) |
added |
number of newly added keys |
updated |
number of newwly updated keys |
deprecated |
number of deprecated keys |
Content Imported Empty 🔗
- Identifier:
import_finished_empty
- The webhook is invoked when importing is finished (from CLI or Gradle). This event is invoked when the importing finished with no changes.
Request Body
{
"type": "import_finished_empty",
"projectId": "_a8402929705887203313",
"customId": "",
"added": 0,
"updated": 0,
"deprecated": 5
}
Field | Description |
---|---|
type |
Webhook event type |
projectId |
the Localazy project identifier |
customId |
the webhook identifier (empty when defined in UI, modifiable over Public API) |
added |
number of newly added keys |
updated |
number of newwly updated keys |
deprecated |
number of deprecated keys |
Project Published 🔗
- Identifier:
project_published
- Triggered when the project is successfully published (applies to release tags too)
Request Body
{
"type": "project_published",
"projectId": "_a8404215906455781329",
"customId": "custom ID",
"tag": "latest"
}
Field | Description |
---|---|
type |
Webhook event type |
projectId |
the Localazy project identifier |
customId |
the webhook identifier (empty when defined in UI, modifiable over Public API) |
tag |
the latest tag or a tag created by Released Tags |
Tag Promoted 🔗
- Identified:
tag_promoted
- Triggered whenever a release tag is promoted to another tag (see release tags)
Request Body
{
"type" : "tag_promoted",
"projectId" : "_a8404215906455781329",
"customId": "custom ID",
"sourceTag" : "latest",
"targetTag" : "production"
}
Webhook secrets 🔗
[GET] /projects/{projectId}/webhooks/secret
Retrieve webhooks secret for current project.
Request 🔗
curl --request GET \
--url https://testing.localazy.com/api/project/test-project/webhooks/secret \
--header 'Authorization: Bearer {{token}}'
Response 🔗
{
"secret": "a webhook secret",
}