> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coingecko.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

> Get notified instantly when events happen on CoinGecko — no polling required

## Why Use Webhooks?

Keep your application synchronized with CoinGecko in real-time — no cron jobs or polling required. Listen to events like `cg.coin.info.updated` and react instantly to changes.

> [card] Automated Asset Updates
>
> Update your UI when a token rebrands, changes ticker, or updates its logo.

> [card] Cross-Chain Monitoring
>
> Detect when a project deploys on a new chain or migrates a contract address.

> [card] Risk & Compliance
>
> Act immediately on critical alerts — malicious activity warnings or contract migration notices.

> [!TIP]
>
> CoinGecko Webhooks (Beta) is available for [paid plan](https://www.coingecko.com/en/api/pricing) customers (Basic plan & above).
>
> * Credit charge: **10** credits per event delivery. Retry attempts are **not charged**.
> * Maximum webhook endpoints: **1** on Basic plan, **5** on Analyst plan & above.
> * **Enterprise** clients who need higher limits — contact your Customer Success Manager.
>
> CoinGecko Webhooks is a supplementary delivery mechanism for real-time notifications. Currently in beta — excluded from the SLA applicable to the CoinGecko API Platform.

> [card] [Share Feedback](https://tally.so/r/2EgG4p)
>
> Help us improve Webhooks — share your suggestions and use cases.

## Getting Started

**1. Create a webhook**

Go to the [Developer Dashboard](https://www.coingecko.com/en/developers/dashboard#webhook) and create a new webhook endpoint.

![](https://mintcdn.com/coingecko/i9l2MT4etZGYjSx8/assets/images/webhook-create.png?fit=max\&auto=format\&n=i9l2MT4etZGYjSx8\&q=85\&s=a1355e0de85fcee5efc0d34e1fc5660c)

CoinGecko generates a unique Signing Secret (`whsec...`) for each webhook.

**2. Get your Signing Secret**

Use the Signing Secret to verify incoming payloads on your server.

![](https://mintcdn.com/coingecko/i9l2MT4etZGYjSx8/assets/images/webhook-signing-secret.png?fit=max\&auto=format\&n=i9l2MT4etZGYjSx8\&q=85\&s=ce14532f00f2b17222055bd3301be6c3)

Every request includes `x-cg-signature`, `x-cg-timestamp`, and `x-cg-event-id` headers for verification.

**3. Start receiving events**

Your server will receive POST requests whenever relevant coin data changes on [CoinGecko.com](https://www.coingecko.com).

> [!NOTE]
>
> For team accounts, non-owner users invited to a shared dashboard have full access to view, edit, and delete webhooks.

## Event Types

| Event Type | Description |
| - | - |
| [cg.coin.info.updated](https://docs.coingecko.com/webhooks/cg-coin-info-updated.md) | Core coin information updated (metadata, links, categories, etc.) |
| [cg.coin.price.moved](https://docs.coingecko.com/webhooks/cg-coin-price-moved.md) | Top-100 coin by market cap makes a significant price move |
| [cg.coin.listed](https://docs.coingecko.com/webhooks/cg-coin-listed.md) | New token indexed and listed on CoinGecko |
| [cg.coin.exchange.added](https://docs.coingecko.com/webhooks/cg-coin-exchange-added.md) | Coin newly tracked on an exchange by CoinGecko |
| More coming soon! | [Share your suggestions](https://tally.so/r/2EgG4p) |

## HTTP Headers

Every webhook POST request includes these headers:

| Header | Description |
| - | - |
| `Content-Type` | `application/json` |
| `x-cg-timestamp` | UNIX timestamp of the event. Useful for replay attack prevention |
| `x-cg-signature` | HMAC SHA256 signature to verify authenticity |
| `x-cg-event-id` | Unique identifier for the event |

## Signature Verification

Verify that incoming payloads are genuinely from CoinGecko by computing an HMAC SHA256 hash and comparing it to the `x-cg-signature` header.

**Signing string format:** `{timestamp}:{event_id}:{json_body}`

> [!WARNING]
>
> The `{json_body}` must be the **raw, unparsed request body** — not a re-stringified JSON object.\\
>
> If your framework auto-parses JSON before verification, the signature will fail.

### Example Code

> Replace `YOUR_SIGNING_SECRET` with the `whsec_...` value from your [Developer Dashboard](https://www.coingecko.com/en/developers/dashboard#webhook).

```js Node.js (Express) expandable theme={null}
const { createHmac } = require('crypto');
const express = require('express');
const app = express();

const SIGNING_SECRET = 'YOUR_SIGNING_SECRET';

function verifySignature(body, headers, secret) {
  if (!secret) return null;

  const timestamp = headers["x-cg-timestamp"];
  const eventId = headers["x-cg-event-id"];
  const signature = headers["x-cg-signature"];

  if (!timestamp || !eventId || !signature) return null;

  const signingString = `${timestamp}:${eventId}:${body}`;
  const expected = createHmac("sha256", secret).update(signingString).digest("hex");

  return expected === signature;
}

app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const rawBodyString = req.body.toString('utf8');
  const isValid = verifySignature(rawBodyString, req.headers, SIGNING_SECRET);

  if (isValid === null) {
    return res.status(400).send('Missing required CoinGecko headers');
  }

  if (isValid) {
    const event = JSON.parse(rawBodyString);
    // Process the event...
    return res.status(200).send('Webhook received successfully');
  } else {
    return res.status(401).send('Invalid signature');
  }
});

app.listen(3000, () => console.log('Server listening on port 3000'));
```

```python Python (Flask) expandable theme={null}
import hmac
import hashlib
from flask import Flask, request

app = Flask(__name__)
SIGNING_SECRET = 'YOUR_SIGNING_SECRET'

def verify_signature(body_str, headers, secret):
    if not secret:
        return None

    timestamp = headers.get('x-cg-timestamp')
    event_id = headers.get('x-cg-event-id')
    signature = headers.get('x-cg-signature')

    if not timestamp or not event_id or not signature:
        return None

    signing_string = f"{timestamp}:{event_id}:{body_str}"

    expected = hmac.new(
        secret.encode('utf-8'),
        signing_string.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()

    return hmac.compare_digest(expected, signature)

@app.route('/webhook', methods=['POST'])
def webhook_handler():
    raw_body_string = request.get_data(as_text=True)
    is_valid = verify_signature(raw_body_string, request.headers, SIGNING_SECRET)

    if is_valid is None:
        return "Missing required CoinGecko headers", 400

    if is_valid:
        event = request.get_json()
        # Process the event...
        return "Webhook received successfully", 200
    else:
        return "Invalid signature", 401

if __name__ == '__main__':
    app.run(port=3000)
```

> [!WARNING]
>
> Treat your Signing Secret like a password — never commit it to public repos or expose it in client-side code.

## Managing Webhooks

Navigate to your **Webhook Details** page in the [Developer Dashboard](https://www.coingecko.com/en/developers/dashboard#webhook):

* **Send Test Event** — dispatches a mock `cg.coin.info.updated` payload. Use it to verify your server receives the request and responds with `2xx` before going live.
* **Delivery Logs** — view the latest 100 delivery attempts. Use these to identify if your endpoint is rejecting requests.

## Billing & Credits

* **10 credits** per event delivery. Retries are **not charged**.
* If you run out of credits with Hardcap enabled (Overage disabled):
  * Delivery stops immediately and all webhooks are auto-disabled.
  * You'll receive an email notification that delivery has stopped.
  * You must **manually re-activate** webhooks in the [Developer Dashboard](https://www.coingecko.com/en/developers/dashboard#webhook) after credits are replenished.

### Estimated Usage

Each delivered webhook event consumes **10 credits**. The `cg.coin.info.updated` event listens to all active coins on CoinGecko — volume fluctuates based on market activity and how frequently projects update their metadata.

* **Expected volume:** up to **200 updates/day** based on historical data.
* **Estimated monthly cost:** \~6,000 events/month = **\~60,000 credits**.
* **Plan fit:** comfortably within the [Analyst plan](https://www.coingecko.com/en/api/pricing) and above.

> [!NOTE]
>
> These are approximations. Extreme market volatility or mass migrations could temporarily increase daily volume.

### 24-Hour Baseline Test

If you're concerned about unpredictable credit usage, run a short test before committing:

1. **Enable Hardcap** — turn OFF "Overage" in the Developer Dashboard to avoid unexpected charges.
2. **Run for 24–48 hours** — activate your webhook and let it collect events.
3. **Check consumption** — review credit usage in the dashboard to establish a reliable baseline.

## Retries & Failed Attempts

If your server fails to respond with a `2xx` status code, CoinGecko will retry with exponential backoff. **Retry attempts are not charged.**

A webhook is automatically disabled under either condition:

| Condition | Threshold |
| - | - |
| Single event backoff | **14 failed retries** over \~24 hours |
| Aggregate failure cap | **300 failed retries** across 12 hours |

When a webhook is disabled, you'll receive an email notification. To resume:

1. Check your server logs and resolve the issue.
2. Log in to the [Developer Dashboard](https://www.coingecko.com/en/developers/dashboard#webhook).
3. Manually toggle the webhook back to **Active**.

[![Pay for your CoinGecko API subscription with crypto](https://mintcdn.com/coingecko/yjZhP2nyEyOfbu6r/assets/images/crypto-payment-banner.png?fit=max\&auto=format\&n=yjZhP2nyEyOfbu6r\&q=85\&s=514a832a4b5a98d03da8a0aad722bceb)](https://docs.coingecko.com/docs/crypto-payment.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.