Skip to main content

Webhook

How to Use Webhooks​

You can register webhooks so that your app can receive events occurring within Gency in real time.

Registering a Webhook​

In the API Center, click Create New Webhook and enter the following items.

  • Name (required, up to 100 characters): A name that identifies the webhook
  • URL (required, HTTPS only, up to 500 characters): The endpoint to which a POST request is sent when an event occurs
  • Subscribed Events: Select the event types to receive via checkboxes

Supported Event Types​

EventDescription
product.createdA product was created
product.deletedA product was deleted
product.pending_reviewChanged to pending review status
product.in_reviewChanged to in review status
product.review_completedReview was completed
product.creation_failedProduct creation failed

Event Payload​

When an event occurs, a POST request in the following format is sent to the registered URL. The event field is common, while the internal structure of data varies by event type.

product.pending_review / product.in_review / product.review_completed​

Sent when a product's review status changes.

{
"event": "product.review_completed",
"data": {
"products": [
{
"workspaceId": "01HABC...",
"productId": "01HXYZ...",
"projectId": "my-project-01",
"productName": "겨울 패딩 자켓",
"status": "REVIEW_COMPLETE",
"category": "OUTER",
"productType": "FASHION",
"createdId": "01HUSR...",
"createdAt": "2025-01-01T00:00:00+09:00"
}
]
}
}
FieldTypeDescription
productsArrayList of products whose status changed
products[].workspaceIdStringWorkspace ID
products[].productIdStringProduct ID
products[].projectIdStringManagement name
products[].productNameStringProduct name
products[].statusStringChanged status (BEFORE_REVIEW: before review, IN_REVIEW: in review, REVIEW_COMPLETE: review complete, CREATION_FAILED: creation failed)
products[].categoryStringCategory
products[].productTypeStringProduct type (FASHION, JEWELRY)
products[].createdIdStringCreator ID
products[].createdAtStringCreation timestamp (ISO 8601)

product.created​

Sent when a product is created.

{
"event": "product.created",
"data": {
"products": [
{
"workspaceId": "01HABC...",
"productId": "01HXYZ...",
"projectId": "my-project-01",
"productName": "겨울 패딩 자켓",
"status": "BEFORE_REVIEW",
"category": "OUTER",
"productType": "FASHION",
"createdId": "01HUSR...",
"createdAt": "2025-01-01T00:00:00+09:00"
}
]
}
}

product.creation_failed​

Sent when product creation fails.

{
"event": "product.creation_failed",
"data": {
"products": [
{
"workspaceId": "01HABC...",
"productId": "01HXYZ...",
"projectId": "my-project-01",
"productName": "겨울 패딩 자켓",
"status": "CREATION_FAILED",
"category": "OUTER",
"productType": "FASHION",
"createdId": "01HUSR...",
"createdAt": "2025-01-01T00:00:00+09:00"
}
]
}
}

The payload structure is identical to the status change events. status is set to PRODUCT_STATUS_05 (creation failed).

product.deleted​

Sent when a product is deleted.

{
"event": "product.deleted",
"data": {
"products": [
{
"workspaceId": "01HABC...",
"productId": "01HXYZ...",
"productName": "겨울 패딩 자켓"
}
]
}
}
FieldTypeDescription
productsArrayList of deleted products
products[].workspaceIdStringWorkspace ID
products[].productIdStringProduct ID
products[].productNameStringProduct name

Retry Policy​

If a webhook delivery fails, the system automatically retries. Including the initial delivery, it attempts up to 5 times (1 initial + 4 retries), with the interval increasing using exponential backoff.

  • Success criterion: HTTP response code 200 ~ 299
  • Failure handling: Response codes outside the above range, timeouts (30 seconds), network errors, etc. are all treated as failures.
  • If all 5 retries fail, the delivery is treated as a final failure.
  • Delivery records for all attempts (HTTP status code, response time, error message) are retained for 30 days.

Webhook Registration Limit​

You can register up to 10 webhooks per master. Deleted webhooks are not counted toward the limit, so if you have reached the limit, you can register a new one by deleting an unused webhook.

Signature Verification (Optional)​

When a webhook is created, a Signing Secret is automatically issued (in the whsec_{32자 랜덤문자열} format). Signature verification is not required, but it is recommended in production environments to prevent forged requests.

Each webhook request includes the following headers.

HeaderDescription
X-Webhook-Signaturesha256={HMAC-SHA256 서명값}
X-Webhook-TimestampRequest delivery time (Unix timestamp)
Content-Typeapplication/json

Verification method:

  1. Extract the timestamp from the X-Webhook-Timestamp header.
  2. Build the message to sign in the {타임스탬프}.{요청 body} format.
  3. Compute the HMAC-SHA256 signature using the Signing Secret as the key.
  4. Compare the computed signature with the value of the X-Webhook-Signature header.
// 검증 예시 (Java)
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;

public boolean verifyWebhook(String payload, String timestamp, String signature, String secret) {
String message = timestamp + "." + payload;
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secret.getBytes(), "HmacSHA256"));
byte[] hash = mac.doFinal(message.getBytes());
StringBuilder hex = new StringBuilder();
for (byte b : hash) {
hex.append(String.format("%02x", b));
}
String expected = "sha256=" + hex.toString();
return MessageDigest.isEqual(expected.getBytes(), signature.getBytes());
}

Reissue Secret​

Clicking the Reissue Secret button issues a new Signing Secret. The existing secret is immediately invalidated, so you must apply the new secret to your server before using it.

Status Management​

A webhook can have the following statuses.

StatusDescription
ACTIVEDelivered normally when an event occurs
INACTIVEEvent delivery is temporarily suspended

If you want to temporarily stop receiving webhooks, you can deactivate it, and deleting it removes it completely.