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

> ## Agent Instructions
> Logo.dev serves logos and brand data for companies that already exist. It does not design logos. If someone wants a logo designed, say so and stop.
> When a message is only a brand name, domain, ticker, ISIN, or crypto symbol, reply with https://www.logo.dev/search?q=<url-encoded term> and the matching img.logo.dev call. Never assert whether a specific brand is in the index.
> Image URLs come from img.logo.dev with a publishable key in the token query parameter: https://img.logo.dev/:domain?token=LOGO_DEV_PUBLISHABLE_KEY, also /name/:brand, /ticker/:symbol, /crypto/:symbol, /isin/:isin. JSON comes from api.logo.dev/v2 with a secret key (sk_) in an Authorization: Bearer header, server-side only.
> Product names: the Logo CDN serves images from img.logo.dev. The Logo API is the Brand API and the Search API, which return JSON from api.logo.dev/v2. The Transaction Enrichment API (beta) is a separate service at https://www.logo.dev/api/transaction with its own beta key. Credits is the Logo API billing unit. Never recommend the deprecated v1 routes (/search, /brand, /describe, /logo/*) or the Describe API. Use /v2/brands and /v2/search.
> Report a wrong, missing, or outdated logo at https://www.logo.dev/update. Email support@logo.dev for anything broken and sales@logo.dev for volume pricing and contract terms.
> MCP setup is at https://www.logo.dev/docs/mcp/introduction and webhooks at https://www.logo.dev/docs/webhooks.

# Create a webhook endpoint

> Register a URL to receive brand webhook events.

<Card title="Get your API keys" icon="key" href="https://www.logo.dev/dashboard/api-keys" horizontal arrow>
  Your dashboard has a publishable key for the Logo CDN and a secret key for the Logo API. Every plan includes both.
</Card>


## OpenAPI

````yaml /openapi.json post /v2/webhook_endpoints
openapi: 3.1.0
info:
  title: Logo.dev API
  description: >-
    Logo.dev serves brand assets from two hosts, each with its own key:


    - **Logo CDN** (`img.logo.dev`) returns a logo image. Authenticate with a
    **publishable key** in the `token` query parameter. It is safe in
    client-side code.

    - **Logo API** (`api.logo.dev`) returns JSON. Authenticate with a **secret
    key** in the `Authorization: Bearer` header. Call it only from your server.


    Get your keys from the [dashboard](https://www.logo.dev/dashboard/api-keys).
  version: 2.0.0
  contact:
    name: Logo.dev Support
    email: support@logo.dev
    url: https://docs.logo.dev
servers:
  - url: https://api.logo.dev
    description: REST APIs (Brand Search, Brand Data)
security: []
tags:
  - name: Logo CDN
    description: >-
      Logo images served from img.logo.dev. Authenticate with a publishable key
      in the `token` query parameter. Metered in monthly impressions.
  - name: Brands
    description: >-
      Brand profiles, logos, and brandmarks as JSON from api.logo.dev. Metered
      in API credits.
  - name: Logos
    description: >-
      A brand's logo or brandmark as JSON, with a temporary download URL,
      dimensions, and a blurhash.
  - name: Search
    description: Find brands by name.
  - name: Subscriptions
    description: Choose which brands send you webhook events.
  - name: Webhook endpoints
    description: Manage the URLs that receive webhook events.
  - name: Transaction Enrichment API
    description: Turn a card transaction descriptor into a merchant identity. Private beta.
paths:
  /v2/webhook_endpoints:
    post:
      tags:
        - Webhook endpoints
      summary: Create a webhook endpoint
      description: >-
        Registers a URL to receive webhook events. Needs a paid plan and the
        owner or admin role. See [Who can use
        webhooks](/webhooks#who-can-use-webhooks).
      operationId: v2CreateWebhookEndpoint
      requestBody:
        required: true
        content:
          application/json:
            schema:
              allOf:
                - $ref: '#/components/schemas/V2WebhookEndpointInput'
              required:
                - url
            example:
              url: https://hooks.example.com/logo-dev
              description: Production
              filter_types:
                - brand.updated
      responses:
        '201':
          description: The endpoint was created.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/V2WebhookEndpoint'
                  metadata:
                    $ref: '#/components/schemas/V2Metadata'
                required:
                  - data
                  - metadata
              example:
                data:
                  object: webhook_endpoint
                  id: ep_2mX9kL4pQ7rT1vW3yZ5aB8cD0e
                  url: https://hooks.example.com/logo-dev
                  description: Production
                  disabled: false
                  filter_types:
                    - brand.updated
                  created_at: '2026-09-21T12:00:00Z'
                  updated_at: '2026-09-21T12:00:00Z'
                metadata:
                  request_id: request_01k6z8m2a4b5c6d7e8f9g0h1j2
        '400':
          description: >-
            The body is invalid: a blank `url`, an unknown event type, or
            malformed JSON.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/V2Error'
              example:
                error:
                  code: invalid_request
                  message: >-
                    unknown event type 'brand.deleted': must be one of
                    brand.updated, brand.indexed: bad format
                docs_url: https://www.logo.dev/docs/platform/errors
        '401':
          $ref: '#/components/responses/V2Unauthorized'
        '403':
          $ref: '#/components/responses/V2WebhooksNotEnabled'
        '409':
          $ref: '#/components/responses/V2LimitExceeded'
        '500':
          description: Managing the endpoint failed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/V2Error'
              example:
                error:
                  code: internal
                  message: failed to manage webhook endpoint
                docs_url: https://www.logo.dev/docs/platform/errors
      security:
        - secretKey: []
components:
  schemas:
    V2WebhookEndpointInput:
      type: object
      properties:
        url:
          type: string
          format: uri
          description: Where deliveries are sent.
        description:
          type: string
        filter_types:
          type: array
          items:
            type: string
            enum:
              - brand.updated
              - brand.indexed
          description: Event types to receive. Omit or send `[]` for all of them.
        disabled:
          type: boolean
          description: Send `true` to create or keep the endpoint switched off.
    V2WebhookEndpoint:
      type: object
      properties:
        object:
          type: string
          const: webhook_endpoint
        id:
          type: string
          examples:
            - ep_2mX9kL4pQ7rT1vW3yZ5aB8cD0e
        url:
          type: string
          format: uri
        description:
          type: string
          description: Empty string when unset.
        disabled:
          type: boolean
          description: >-
            `true` when you switched the endpoint off, or when deliveries were
            stopped after sustained failures.
        filter_types:
          type: array
          items:
            type: string
            enum:
              - brand.updated
              - brand.indexed
          description: >-
            Event types this endpoint receives. An empty array means all of
            them.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - object
        - id
        - url
        - description
        - disabled
        - filter_types
        - created_at
        - updated_at
    V2Metadata:
      type: object
      properties:
        request_id:
          type: string
          description: Unique id for this request. Also sent as the `Request-Id` header.
          examples:
            - request_01k6z8m2a4b5c6d7e8f9g0h1j2
        resolution:
          allOf:
            - $ref: '#/components/schemas/V2Resolution'
          description: Brand and image lookups only.
        pending:
          allOf:
            - $ref: '#/components/schemas/V2Pending'
          description: '`202` responses only.'
        subscription:
          type: object
          description: >-
            Present when a brand lookup (`GET /v2/brands` or `GET
            /v2/brands/{id}`) ran the automatic subscribe: webhooks are on for
            the account, and `nosubscribe` is not `true`. See [automatic
            subscriptions](/brand/introduction#automatic-subscriptions).
          properties:
            status:
              type: string
              enum:
                - subscribed
                - quota_exceeded
              description: >-
                `subscribed`: the account is subscribed to the brand.
                `quota_exceeded`: the account is at its plan's subscription
                limit, so the brand was not subscribed. The lookup is answered
                and billed either way.
            message:
              type: string
              description: Why the subscribe was refused. Only with `quota_exceeded`.
          required:
            - status
      required:
        - request_id
    V2Error:
      type: object
      description: Error envelope for v2 routes.
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - invalid_request
                - unauthorized
                - forbidden
                - resource_missing
                - insufficient_credits
                - rate_limited
                - limit_exceeded
                - internal
            message:
              type: string
            target:
              type: string
              description: The parameter at fault, when there is exactly one.
          required:
            - code
            - message
        docs_url:
          type: string
          format: uri
          description: Documentation for this class of error.
      required:
        - error
    V2Resolution:
      type: object
      description: How the request identified the brand.
      properties:
        type:
          type: string
          enum:
            - domain
            - ticker
            - isin
            - crypto
            - name
            - brand_id
          description: Which identifier the request used.
        value:
          type: string
          description: >-
            The identifier after normalization: the registrable domain, an
            upper-cased ticker, and so on.
        method:
          type: string
          enum:
            - direct
            - domain
            - security
            - crypto
            - search
            - ''
          description: >-
            How the identifier reached the brand. `direct` is a brand id or a
            domain that is its own brand; `domain` went through an alias or
            redirect; `security` is a ticker or ISIN; `crypto` is a crypto token
            symbol; `search` is a name lookup. Empty on a cached miss.
        context:
          type: object
          description: >-
            Reserved for brands involved in a merchant lookup. Always `{}`
            today.
      required:
        - type
        - value
        - method
        - context
    V2Pending:
      type: object
      description: Present only on a `202`. Tells you when to retry.
      properties:
        reason:
          type: string
          enum:
            - indexing
            - resolving
          description: >-
            `indexing` is a brand's first crawl; `resolving` means the
            identifier is still being matched to a brand.
        message:
          type: string
        retry_after_seconds:
          type: integer
          description: Wait this long before retrying. Matches the `Retry-After` header.
          examples:
            - 30
        expires_in_seconds:
          type: integer
          description: Stop polling after this long.
          examples:
            - 300
        webhook:
          type: boolean
          description: >-
            Whether a `brand.indexed` webhook event carrying this request's
            `request_id` will be sent when the lookup settles.
        doc_url:
          type: string
          format: uri
      required:
        - reason
        - message
        - retry_after_seconds
        - expires_in_seconds
        - webhook
        - doc_url
    V2AuthError:
      type: object
      description: >-
        Returned when the secret key is missing, malformed, unknown, or
        disabled, before the request reaches the v2 route.
      properties:
        msg:
          type: string
        docs_url:
          type: string
          format: uri
      required:
        - msg
  responses:
    V2Unauthorized:
      description: >-
        The secret key is missing, malformed, unknown, or disabled. A
        publishable key (`pk_`) is refused.
      content:
        application/json:
          schema:
            oneOf:
              - $ref: '#/components/schemas/V2AuthError'
              - $ref: '#/components/schemas/V2Error'
          example:
            msg: invalid api token. make sure to use your secret key.
            docs_url: https://www.logo.dev/docs/platform/api-keys
    V2WebhooksNotEnabled:
      description: >-
        Your plan does not include webhooks, or your role cannot change them.
        See [Who can use webhooks](/webhooks#who-can-use-webhooks).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/V2Error'
          example:
            error:
              code: forbidden
              message: organization admin role required to change webhooks
            docs_url: https://www.logo.dev/docs/platform/errors
    V2LimitExceeded:
      description: >-
        Your account is at its plan's limit for this resource. Delete one, or
        upgrade. See [plan limits](/webhooks#plan-limits).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/V2Error'
          examples:
            subscriptions:
              value:
                error:
                  code: limit_exceeded
                  message: >-
                    brand subscription limit reached. the pro plan allows
                    {limit} subscriptions: limit exceeded
                docs_url: https://www.logo.dev/docs/platform/errors
            webhook_endpoints:
              value:
                error:
                  code: limit_exceeded
                  message: >-
                    webhook endpoint limit reached. the pro plan allows {limit}
                    endpoints: limit exceeded
                docs_url: https://www.logo.dev/docs/platform/errors
  securitySchemes:
    secretKey:
      type: http
      scheme: bearer
      description: >-
        Your secret key (`sk_`), as `Bearer sk_...`. Call the Logo API only from
        your server.

````

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