Claim Status Webhook

Webhook endpoint documentation for claim status change notifications. This endpoint represents the structure of webhook payloads sent to your configured webhook URL when claim statuses change.

Recent Requests
Log in to see full request history
TimeStatusUser Agent
Retrieving recent requests…
LoadingLoading…

Webhook requests

Authentication and Processing

Webhooks sent from Extend require digital signature verification. Once verified, the webhooks can be processed for business logic.

  • The webhook payload is JSON.
  • The signature is sent as a signature header.
  • Extend's public key id is sent as the X-Extend-Key-Id header.
  • Extend's key id is also sent in the webhook request payload as kid. Confirm that the value of X-Extend-Key-Idand kid match.

As part of the verification flow, you will need to make an HTTP GET request to Extend's JWKS endpoint: https://api.helloextend.com/service-orders/oauth/keys.

Request

GET https://api.helloextend.com/service-orders/oauth/keys

Example Response

{
  "keys": [
    {
      "kty": "RSA",
      "alg": "RS256",
      "use": "sig",
      "key_ops": [
        "sign",
        "verify"
      ],
      "kid": "b35edb9f-4be9-4cb4-9425-6f3d04ac9347",
      "n": "tvFPcO-lSUcW9n_dv45wfY0yF47CXZLICqS5kWIypfpP2NX4WRDK8c0bXx6g9P4n_UjJqyDsa-ocMil2dWRDn2oGCzrZLvk6bwerQfCij0Qvy92YZAWJ8r2QrQN69LZzrzCqpMbleclb4du5L46tIdWpOuWx9JWOD_F_HROyd26-SIUvrsLnk7pjSsRx1Bp9mw-qjIB2tEFCINrD3IDcFicPKMpWImhNA-Bukq3ZySzq2VvqAqmhif5EsLw4XWXOucM7YWLn5MfscRippwky94emVD4Hc3LaIYdjxcSMd9Gyr4vgEQU-sgj_hrBfjCabLEsfELIbrC4aPaNN1VTar91ErycEtmH5fNAhI7ka1YUFt5-AgvXDcPs4vnHuTX86TG_0IMhSxr-jvdarYJbTdbLU2-ViRSjIc3FSg4qjvxmyfJNXkwIWHy5Mh3kEK3GA573GofyCTjo20IwjNwhys0PdMnC9YXJQATPE4BvADaaA4UiKDeMfpOXA4Y6dgA9HDRVoA0RgNAycfHh0eIyjnOZjaU7napAxQjr7xqTw_8d8_MpCdAaAb70iL5pbbAtXpuhB27fvKNgvQGD3-X6idEbMYuJmZHzqDMfEmJROd4SjQl0OR5Lay5KpZyvjVsskh0GEbU_HR87UYP8FJn-avDhG6jU-HtSDJahACXeaS-s",
      "e": "AQAB"
    }
  ]
}
  • Parse the JSON response which contains an array of keys in JWK format. Find the specific key that matches the kid from the webhook payload.
  • Convert the JWK (JSON Web Key) to PEM format, which is required for most signature verification libraries. This typically involves using a crypto library to create a public key object from the JWK and exporting it in PEM format. Here is an example using the cryptoNode module.
/**
 * Convert a JWK to PEM format
 *
 * @param jwk - The JWK object (the full key Object from the 'keys' array)
 * @returns PEM formatted key
 */
function jwkToPem(jwk: any): string {
  try {
    const publicKey = crypto.createPublicKey({
      key: jwk as unknown as NodeJsonWebKey,
      format: 'jwk',
    })
    return publicKey.export({ type: 'spki', format: 'pem' }).toString()
  } catch (error) {
    Log.error('Error converting JWK to PEM', error)
    throw error
  }
}

Verify the Digital Signature. Use a cryptographic library to verify that the signature was created using the private key corresponding to the public key. The verification should use the RSA-SHA256 algorithm. The signature is typically base64-encoded and needs to be decoded before verification.

import crypto from 'crypto'
/**
 * Returns true if signature verification passed
 *
 * @param body - Stringified body of the webhook
 * @param publicKey - Base64 encoded publicKey. 
 * @param signature - Base64 encoded signature. Found in webhook ['signature'] header.
 * The signature found in the request header is Base64 encoded.
 * @returns true if the verification passed
 */
function verifyDigitalSignature(
  body: string,
  publicKey: string,
  signature: string,
): boolean {
  try {
    return crypto.verify(
      'RSA-SHA256',
      Buffer.from(body),
      Buffer.from(publicKey, 'base64'),
      Buffer.from(signature, 'base64'),
    )
  } catch (e) {
    return false
  }
}

// Example usage
const publicKey = 'LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUF0dkZQY08rbFNVY1c5bi9kdjQ1dwpmWTB5RjQ3Q1haTElDcVM1a1dJeXBmcFAyTlg0V1JESzhjMGJYeDZnOVA0bi9VakpxeURzYStvY01pbDJkV1JECm4yb0dDenJaTHZrNmJ3ZXJRZkNpajBRdnk5MllaQVdKOHIyUXJRTjY5TFp6cnpDcXBNYmxlY2xiNGR1NUw0NnQKSWRXcE91V3g5SldPRC9GL0hST3lkMjYrU0lVdnJzTG5rN3BqU3NSeDFCcDltdytxaklCMnRFRkNJTnJEM0lEYwpGaWNQS01wV0ltaE5BK0J1a3EzWnlTenEyVnZxQXFtaGlmNUVzTHc0WFdYT3VjTTdZV0xuNU1mc2NSaXBwd2t5Cjk0ZW1WRDRIYzNMYUlZZGp4Y1NNZDlHeXI0dmdFUVUrc2dqL2hyQmZqQ2FiTEVzZkVMSWJyQzRhUGFOTjFWVGEKcjkxRXJ5Y0V0bUg1Zk5BaEk3a2ExWVVGdDUrQWd2WERjUHM0dm5IdVRYODZURy8wSU1oU3hyK2p2ZGFyWUpiVApkYkxVMitWaVJTakljM0ZTZzRxanZ4bXlmSk5Ya3dJV0h5NU1oM2tFSzNHQTU3M0dvZnlDVGpvMjBJd2pOd2h5CnMwUGRNbkM5WVhKUUFUUEU0QnZBRGFhQTRVaUtEZU1mcE9YQTRZNmRnQTlIRFJWb0EwUmdOQXljZkhoMGVJeWoKbk9aamFVN25hcEF4UWpyN3hxVHcvOGQ4L01wQ2RBYUFiNzBpTDVwYmJBdFhwdWhCMjdmdktOZ3ZRR0QzK1g2aQpkRWJNWXVKbVpIenFETWZFbUpST2Q0U2pRbDBPUjVMYXk1S3BaeXZqVnNza2gwR0ViVS9IUjg3VVlQOEZKbithCnZEaEc2alUrSHRTREphaEFDWGVhUytzQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQ==';

const requestBody = '{"serviceOrderId":"73752710-8cdf-4fe3-8327-6936fa3badd6","claimId":"7b67180d-0ae6-4d81-a0ca-d7eeda41870e","contractId":"770e5f9d-fb2d-4c53-9137-cbb647d037f5","servicerId":"26db19a3-d9db-4ad4-9575-b7ca2f6e990a","customerName":"Paul Name","customerEmail":"[email protected]","contractPurchaseDate":1655668093818,"customerShippingAddress":{"city":"San Francisco","address1":"533 Mission Street","provinceCode":"CA","countryCode":"USA","postalCode":"94105"},"customerPhoneNumber":"555-535-5555","productDetails":[{"productReferenceId":"PRODUCT-REPAIR-385UmuLNaUqVmpohrmnvMqrncttQCz","productListPrice":25199,"productPurchasePrice":25199}],"failureType":"webhook parse","failureDescription":"webhook","incident":{"failureType":"electricalFailure","description":"BROKE PLZ HALP","occurredAt":1695152893819,"FailureType":"webhook parse","FailureDescription":"webhook","productCondition":"nonfunctional"},"sendDate":1695152952396,"url":"https://webhook.site/70a09585-f934-4b01-855b-0869e5e19752","transactionId":"63815176-f685-44ca-8180-fb13e39d5d04","type":"assign"}';
const signature = 'JJbRyjmmylP4GJtNCT7wANYVMkmUYENuX13sXqMjbAUcfidBBix/hzCjnoycg6lCT1Ktny2OnmixEHQAwNFOuReTlid+AFvCQnQ0nA+aUjvD3JSYCLLE2SOuvbZ7/Q/fQZNnFrDUX6MXcYkuoNLUmKRagG5uq0UyIEtWgfyLtGJQlZ91KXJkvZsFQu+AO5dFiDceJA+IW11sCN5e/9gKWuHxzxwKepvA8S0lyPwQWYqk1V/O/bV5s5uD5zrI6Wndd8Yq7ejYsWd6ZeHbjrcTbbr35lKsTcpoLxtBjD+H/1X5+pYAPlW7ymLWpPxEAug8tnpzy5HVMtwNZ3br8S5afC9BgR7abGcfa3PjyYvM1tk6+JfCPLa9gIJShu1+eXTq0GUQnxu/0bL/ihnwadHlFZyLVzmRjBkPrsuQsM6KTvXS5Gw+BGo+zy/p7iFUFHws1r6zZNONe0ZxTudpDgGN7IoXmvyj7OOJ7VyGROggB0Ptu2iiNz81uTT1M9z+QCR2pa9E+a6fTWTZIXP86acb8HuKDb8Rd9wkU4G609aZc3QHX0ANKIFSWqhz9WDh0XZgT8daMuda+TmtI4NkTS7j9yQLqvbYQ1W2RpCKVBLgXCgiylBoHfRWFZ/dlOdkojBWaFnWa8ytU69IHFgVAd4V4RVPgjNyWgwovtQtiAvpT3o=';

if (verifyDigitalSignature($signature, $publicKey, $requestBody)) {
    console.log("Signature is valid!")
} else {
    console.log("Signature is not valid.")
}
<?php
// Signature is base64 encoded and found in the 'signature' header on the request
// Public Key returned from Extend API as base64 encoded string
// Request body. Stringified JSON body sent in the webhook request
function verifyDigitalSignature($signature, $publicKey, $requestBody)
{
    // Load the public key
    $publicKeyResource = openssl_pkey_get_public(base64_decode($publicKey));

    if ($publicKeyResource === false) {
        return false; // Failed to load the public key
    }

    // Verify the signature
    $result = openssl_verify($requestBody, base64_decode($signature), $publicKeyResource, OPENSSL_ALGO_SHA256);


    return ($result === 1); // 1 means the signature is valid
}

// Example usage
$publicKey = 'LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUF0dkZQY08rbFNVY1c5bi9kdjQ1dwpmWTB5RjQ3Q1haTElDcVM1a1dJeXBmcFAyTlg0V1JESzhjMGJYeDZnOVA0bi9VakpxeURzYStvY01pbDJkV1JECm4yb0dDenJaTHZrNmJ3ZXJRZkNpajBRdnk5MllaQVdKOHIyUXJRTjY5TFp6cnpDcXBNYmxlY2xiNGR1NUw0NnQKSWRXcE91V3g5SldPRC9GL0hST3lkMjYrU0lVdnJzTG5rN3BqU3NSeDFCcDltdytxaklCMnRFRkNJTnJEM0lEYwpGaWNQS01wV0ltaE5BK0J1a3EzWnlTenEyVnZxQXFtaGlmNUVzTHc0WFdYT3VjTTdZV0xuNU1mc2NSaXBwd2t5Cjk0ZW1WRDRIYzNMYUlZZGp4Y1NNZDlHeXI0dmdFUVUrc2dqL2hyQmZqQ2FiTEVzZkVMSWJyQzRhUGFOTjFWVGEKcjkxRXJ5Y0V0bUg1Zk5BaEk3a2ExWVVGdDUrQWd2WERjUHM0dm5IdVRYODZURy8wSU1oU3hyK2p2ZGFyWUpiVApkYkxVMitWaVJTakljM0ZTZzRxanZ4bXlmSk5Ya3dJV0h5NU1oM2tFSzNHQTU3M0dvZnlDVGpvMjBJd2pOd2h5CnMwUGRNbkM5WVhKUUFUUEU0QnZBRGFhQTRVaUtEZU1mcE9YQTRZNmRnQTlIRFJWb0EwUmdOQXljZkhoMGVJeWoKbk9aamFVN25hcEF4UWpyN3hxVHcvOGQ4L01wQ2RBYUFiNzBpTDVwYmJBdFhwdWhCMjdmdktOZ3ZRR0QzK1g2aQpkRWJNWXVKbVpIenFETWZFbUpST2Q0U2pRbDBPUjVMYXk1S3BaeXZqVnNza2gwR0ViVS9IUjg3VVlQOEZKbithCnZEaEc2alUrSHRTREphaEFDWGVhUytzQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQ==';

$requestBody = '{"serviceOrderId":"73752710-8cdf-4fe3-8327-6936fa3badd6","claimId":"7b67180d-0ae6-4d81-a0ca-d7eeda41870e","contractId":"770e5f9d-fb2d-4c53-9137-cbb647d037f5","servicerId":"26db19a3-d9db-4ad4-9575-b7ca2f6e990a","customerName":"Paul Name","customerEmail":"[email protected]","contractPurchaseDate":1655668093818,"customerShippingAddress":{"city":"San Francisco","address1":"533 Mission Street","provinceCode":"CA","countryCode":"USA","postalCode":"94105"},"customerPhoneNumber":"555-535-5555","productDetails":[{"productReferenceId":"PRODUCT-REPAIR-385UmuLNaUqVmpohrmnvMqrncttQCz","productListPrice":25199,"productPurchasePrice":25199}],"failureType":"webhook parse","failureDescription":"webhook","incident":{"failureType":"electricalFailure","description":"BROKE PLZ HALP","occurredAt":1695152893819,"FailureType":"webhook parse","FailureDescription":"webhook","productCondition":"nonfunctional"},"sendDate":1695152952396,"url":"https://webhook.site/70a09585-f934-4b01-855b-0869e5e19752","transactionId":"63815176-f685-44ca-8180-fb13e39d5d04","type":"assign"}';
$signature = 'JJbRyjmmylP4GJtNCT7wANYVMkmUYENuX13sXqMjbAUcfidBBix/hzCjnoycg6lCT1Ktny2OnmixEHQAwNFOuReTlid+AFvCQnQ0nA+aUjvD3JSYCLLE2SOuvbZ7/Q/fQZNnFrDUX6MXcYkuoNLUmKRagG5uq0UyIEtWgfyLtGJQlZ91KXJkvZsFQu+AO5dFiDceJA+IW11sCN5e/9gKWuHxzxwKepvA8S0lyPwQWYqk1V/O/bV5s5uD5zrI6Wndd8Yq7ejYsWd6ZeHbjrcTbbr35lKsTcpoLxtBjD+H/1X5+pYAPlW7ymLWpPxEAug8tnpzy5HVMtwNZ3br8S5afC9BgR7abGcfa3PjyYvM1tk6+JfCPLa9gIJShu1+eXTq0GUQnxu/0bL/ihnwadHlFZyLVzmRjBkPrsuQsM6KTvXS5Gw+BGo+zy/p7iFUFHws1r6zZNONe0ZxTudpDgGN7IoXmvyj7OOJ7VyGROggB0Ptu2iiNz81uTT1M9z+QCR2pa9E+a6fTWTZIXP86acb8HuKDb8Rd9wkU4G609aZc3QHX0ANKIFSWqhz9WDh0XZgT8daMuda+TmtI4NkTS7j9yQLqvbYQ1W2RpCKVBLgXCgiylBoHfRWFZ/dlOdkojBWaFnWa8ytU69IHFgVAd4V4RVPgjNyWgwovtQtiAvpT3o=';

if (verifyDigitalSignature($signature, $publicKey, $requestBody)) {
    echo "Signature is valid!";
} else {
    echo "Signature is not valid.";
}
?>

If the signature verification succeeds; process the webhook. If verification fails; reject the webhook.

Webhook Request Body

The webhook request body is the same shape for all of the following supported claims events:

approved: 'claim_approved', denied: 'claim_denied', review: 'claim_in_review',

Events can be subscribed to on an individual basis.

{
  // Contract and order identifiers
  contractId?: string
  orderId?: string
  claimId: string

  // Claim details
  claimType: string
  claimStatus: string
  transactionId: string
  remainingLimitOfLiability?: number
  validationReason?: string
  coverageTerm?: {
    startDate: number
    endDate: number
  }

  // Customer and product information
  customer: {
    name: string
    phone?: string
    email: string
    shippingAddress?: {
      address1: string
      address2?: string
      city: string
      provinceCode: string
      countryCode: string
      postalCode: string
    }
  }
  products: {
    referenceId: string
    lineItemId?: string
    limitOfLiability?: number
    title: string
    serialNumber?: string
    selectedVariant?: {
      referenceId?: string
      title?: string
      imageUrl?: string
    }
    imageUrl?: string
    type?: string
    lineItemTransactionId?: string
    contractValue?: number
  }[]
  /** Key-value object with filtered incident/failure details */
  incident: Record<string, unknown>
  /** Epoch ms when the claim was reported */
  reportedAt: number

  // Webhook metadata
  /** Epoch ms when the webhook was sent */
  sendDate: number
  type: 'claim_approved' | 'claim_denied' | 'claim_in_review'
  url: string
  claimDetailsUrl: string
  kid: string

  // Optional fields
  denialReason?: string
	customerSegment?: string
  riskScore?: number
  claimPhotos?: {
    required: number
    uploaded: number
  }
}

Approved Example

{
  "contractId": "51d1699c-c8f4-4e50-893b-16af8adc994a",
  "orderId": "e18c4150-2bcb-4d80-94af-816f9c59e0e1",
  "claimId": "fc47a847-27c8-48c3-a564-68300f5f625b",
  "claimType": "extended_warranty",
  "claimStatus": "approved",
  "transactionId": "6c7278d7-37a5-4253-ba8d-3d266bc68b2a",
  "remainingLimitOfLiability": 2000,
  "validationReason": "shipping_delivery_waiting_period",
  "coverageTerm": {
    "startDate": 1593533340000,
    "endDate": 1593993600000
  },
  "customer": {
    "name": "John Doe",
    "phone": "111-111-1111",
    "email": "[email protected]",
    "shippingAddress": {
      "address1": "1 Main St",
      "address2": "Ste 1",
      "city": "San Francisco",
      "provinceCode": "CA",
      "countryCode": "US",
      "postalCode": "11111"
    }
  },
  "products": [
    {
      "referenceId": "referenceId",
      "lineItemId": "05f40503-33c4-42d8-9441-e060f34b6002",
      "limitOfLiability": 2000,
      "title": "black t-shirt",
      "serialNumber": "SN-2024-XK7892",
      "selectedVariant": {
        "referenceId": "variant-001",
        "title": "Black / Large",
        "imageUrl": "https://cdn.example.com/images/black-tshirt-lg.png"
      },
      "imageUrl": "https://cdn.example.com/images/black-tshirt.png",
      "type": "extended_warranty",
      "lineItemTransactionId": "6c7278d7-37a5-4253-ba8d-3d266bc68b2a",
      "contractValue": 4999
    }
  ],
  "incident": {
    "FailureType": "shipment_lost",
    "FailureDescription": "The package has been rerouted to the correct destination.",
    "Shipment": "1Z57E4700306164050",
    "IncidentDate": 1756699200000,
  },
  "customerSegment": "premium_member",
  "riskScore": 0,
  "claimPhotos": {
    "required": 1,
    "uploaded": 1
  },
  "reportedAt": 1740766088101,
  "sendDate": 1740766088101,
  "type": "claim_approved",
  "url": "https://servicer-webhook-url/post-webhook",
  "claimDetailsUrl": "https://merchants.extend.com/store/claims/fc47a847-27c8-48c3-a564-68300f5f625b",
  "kid": "b35edb9f-4be9-4cb4-9425-6f3d04ac9347"
}

Denied Example

{
  "contractId": "51d1699c-c8f4-4e50-893b-16af8adc994a",
  "orderId": "e18c4150-2bcb-4d80-94af-816f9c59e0e1",
  "claimId": "fc47a847-27c8-48c3-a564-68300f5f625b",
  "claimType": "extended_warranty",
  "claimStatus": "denied",
  "transactionId": "6c7278d7-37a5-4253-ba8d-3d266bc68b2a",
  "remainingLimitOfLiability": 2000,
  "validationReason": "mfr_warranty_active",
  "coverageTerm": {
    "startDate": 1593533340000,
    "endDate": 1593993600000
  },
  "customer": {
    "name": "John Doe",
    "phone": "111-111-1111",
    "email": "[email protected]",
    "shippingAddress": {
      "address1": "1 Main St",
      "address2": "Ste 1",
      "city": "San Francisco",
      "provinceCode": "CA",
      "countryCode": "US",
      "postalCode": "11111"
    }
  },
  "products": [
    {
      "referenceId": "referenceId",
      "lineItemId": "05f40503-33c4-42d8-9441-e060f34b6002",
      "limitOfLiability": 2000,
      "title": "black t-shirt",
      "serialNumber": "SN-2024-XK7892",
      "selectedVariant": {
        "referenceId": "variant-001",
        "title": "Black / Large",
        "imageUrl": "https://cdn.example.com/images/black-tshirt-lg.png"
      },
      "imageUrl": "https://cdn.example.com/images/black-tshirt.png",
      "type": "extended_warranty",
      "lineItemTransactionId": "6c7278d7-37a5-4253-ba8d-3d266bc68b2a",
      "contractValue": 4999
    }
  ],
  "incident": {
    "FailureType": "failure_electrical",
    "FailureDescription": "a",
    "FailureCause": "weather",
    "IncidentDate": 1756699200000
  },
  "reportedAt": 1740766088101,
  "sendDate": 1740766088101,
  "type": "claim_denied",
  "url": "https://servicer-webhook-url/post-webhook",
  "claimDetailsUrl": "https://merchants.extend.com/store/claims/fc47a847-27c8-48c3-a564-68300f5f625b",
  "kid": "b35edb9f-4be9-4cb4-9425-6f3d04ac9347",
  "denialReason": "under_manufacturer_warranty"
}

Webhooks should be responded to with a status code 200. All requests that do not receive a 200 will be retried every hour for 48 hours.

Body Params

Webhook payload sent when claim status changes

string

Contract identifier

string

Order identifier

string
required

Unique claim identifier

string
enum
required

Type of claim

Allowed:
string
enum
required

Status of a claim

Allowed:
string
required

Transaction identifier

number

Remaining limit of liability on the entitlement

string

Reason for validation if claim is in review

coverageTerm
object

Coverage period details

customer
object
required
products
array of objects
required

Products associated with the claim

products*
incident
object
required

Incident details describing the failure

integer
required

When the claim was reported (Unix timestamp)

integer
required

When the webhook was sent (Unix timestamp)

string
enum
required

Type of webhook event

Allowed:
uri
required

Webhook URL where this payload was sent

string
required

Key ID used for webhook signature verification

string
enum

Reason for claim denial

Allowed:
Responses
200

Webhook received and processed successfully

400

Invalid webhook payload

401

Webhook signature verification failed

Language
LoadingLoading…
Response
Click Try It! to start a request and see the response here!