Agree.com · AsyncAPI Specification

Agree.com Webhooks

Version 1.0.0

Real-time event notifications from the Agree contract-to-cash platform. Agree POSTs a signed JSON body to endpoints you register through POST /api/v1/webhooks. Twelve event types are published, covering the invoice lifecycle, the agreement signature lifecycle, and a test event. Delivery is at-least-once with a five-attempt exponential backoff.

View Spec View on GitHub AgreementsElectronic SignatureContract ManagementInvoicingBillingPaymentsAccounts ReceivableFintechFinancial ServicesWebhookMCPAgent-NativeAsyncAPIEventsWebhooks

Channels

webhookEndpoint
The single URL you register. All subscribed event types are delivered to it with the same envelope; the event type is carried in the body's "event" member, not in the path.

Messages

✉
invoiceCreated
Invoice was created
Fires after POST /invoices.
✉
invoiceSent
Invoice emailed to customer
Fires when delivery completes.
✉
invoiceDue
Invoice reached due status
Fires when status becomes due - either the scheduled job runs after sent (past due_at), or the invoice is sent already at or past due_at (immediate due).
✉
invoicePaid
Payment successful
Fires after payment confirmation.
✉
invoiceFailed
Payment attempt failed
Fires after payment rejection. The invoice status becomes failed but the customer can retry payment using the same link.
✉
invoiceCanceled
Invoice was canceled
Fires after DELETE /invoices.
✉
invoiceRefunded
Invoice payment was refunded
Fires after a refund is processed.
✉
agreementCreated
Agreement was created
Fires after POST /agreements.
✉
agreementSent
Agreement was sent to recipients
Fires when status changes to sent.
✉
agreementSigned
Agreement was signed by a recipient
Fires when a recipient signs. Emitted once per signer.
✉
agreementExecuted
Agreement was fully executed
Fires when all signers have signed.
✉
webhookTest
Test event
Fires when you trigger a test via POST /api/v1/webhooks/test.

Servers

https
subscriber
Your own HTTPS endpoint, registered via POST /api/v1/webhooks. HTTPS is required in production. Agree is the publisher; your endpoint is the server that receives.

AsyncAPI Specification

Raw ↑
x-provenance:
  generated: '2026-09-12'
  method: generated
  source: https://secure.agree.com/documentation#tag/Webhooks
  note: >-
    Agree.com publishes no AsyncAPI document. This one is generated faithfully from the
    provider's own published webhook catalog - the "Available Events" table, the payload
    shape, the signature headers and the retry schedule, all documented verbatim in the
    Webhooks tag guide of https://secure.agree.com/documentation/openapi. Every event name,
    description, firing condition and header below is the provider's text. No event, field, or
    schema has been invented. The per-event payloads reuse the Invoice and Agreement schemas
    from the provider's own OpenAPI, as the documentation states they do - "The payload
    contains the complete resource object".
asyncapi: 3.0.0
info:
  title: Agree.com Webhooks
  version: 1.0.0
  description: >-
    Real-time event notifications from the Agree contract-to-cash platform. Agree POSTs a
    signed JSON body to endpoints you register through POST /api/v1/webhooks. Twelve event
    types are published, covering the invoice lifecycle, the agreement signature lifecycle,
    and a test event. Delivery is at-least-once with a five-attempt exponential backoff.
  contact:
    name: Agree Support
    email: support@agree.com
    url: https://secure.agree.com/documentation
  externalDocs:
    description: Agree webhook documentation
    url: https://secure.agree.com/documentation#tag/Webhooks
defaultContentType: application/json
servers:
  subscriber:
    host: your-app.example.com
    protocol: https
    description: >-
      Your own HTTPS endpoint, registered via POST /api/v1/webhooks. HTTPS is required in
      production. Agree is the publisher; your endpoint is the server that receives.
channels:
  webhookEndpoint:
    address: /
    title: Registered webhook endpoint
    description: >-
      The single URL you register. All subscribed event types are delivered to it with the
      same envelope; the event type is carried in the body's "event" member, not in the path.
    messages:
      invoiceCreated:
        $ref: '#/components/messages/invoiceCreated'
      invoiceSent:
        $ref: '#/components/messages/invoiceSent'
      invoiceDue:
        $ref: '#/components/messages/invoiceDue'
      invoicePaid:
        $ref: '#/components/messages/invoicePaid'
      invoiceFailed:
        $ref: '#/components/messages/invoiceFailed'
      invoiceCanceled:
        $ref: '#/components/messages/invoiceCanceled'
      invoiceRefunded:
        $ref: '#/components/messages/invoiceRefunded'
      agreementCreated:
        $ref: '#/components/messages/agreementCreated'
      agreementSent:
        $ref: '#/components/messages/agreementSent'
      agreementSigned:
        $ref: '#/components/messages/agreementSigned'
      agreementExecuted:
        $ref: '#/components/messages/agreementExecuted'
      webhookTest:
        $ref: '#/components/messages/webhookTest'
operations:
  receiveAgreeEvent:
    action: receive
    channel:
      $ref: '#/channels/webhookEndpoint'
    title: Receive an Agree event
    summary: Agree POSTs a signed event envelope to your registered endpoint.
    description: >-
      Return 200 within 5 seconds and process asynchronously. Verify X-Webhook-Signature
      before processing. Non-2xx or timeout triggers the retry schedule.
    bindings:
      http:
        method: POST
    messages:
    - $ref: '#/channels/webhookEndpoint/messages/invoiceCreated'
    - $ref: '#/channels/webhookEndpoint/messages/invoiceSent'
    - $ref: '#/channels/webhookEndpoint/messages/invoiceDue'
    - $ref: '#/channels/webhookEndpoint/messages/invoicePaid'
    - $ref: '#/channels/webhookEndpoint/messages/invoiceFailed'
    - $ref: '#/channels/webhookEndpoint/messages/invoiceCanceled'
    - $ref: '#/channels/webhookEndpoint/messages/invoiceRefunded'
    - $ref: '#/channels/webhookEndpoint/messages/agreementCreated'
    - $ref: '#/channels/webhookEndpoint/messages/agreementSent'
    - $ref: '#/channels/webhookEndpoint/messages/agreementSigned'
    - $ref: '#/channels/webhookEndpoint/messages/agreementExecuted'
    - $ref: '#/channels/webhookEndpoint/messages/webhookTest'
components:
  messageTraits:
    signedEnvelope:
      headers:
        type: object
        properties:
          Content-Type:
            type: string
            const: application/json
          X-Webhook-Signature:
            type: string
            description: HMAC-SHA256 of the raw request body keyed by the endpoint secret, hex, lowercase.
          X-Webhook-Timestamp:
            type: string
            description: Unix timestamp when the event was sent.
        required:
        - X-Webhook-Signature
        - X-Webhook-Timestamp
  schemas:
    envelope:
      type: object
      description: Every Agree webhook body has this two-member shape.
      properties:
        event:
          type: string
          description: The event type.
        payload:
          type: object
          description: The complete resource object for the event's subject.
      required:
      - event
      - payload
    invoicePayload:
      type: object
      description: >-
        The full Invoice resource, identical to the data member of GET /api/v1/invoices/{id}.
        See components.schemas.Invoice in openapi/agree-com-api-openapi.json.
      properties:
        id:
          type: string
          format: uuid
        status:
          type: string
          enum:
          - created
          - due
          - sent
          - canceled
          - paid
          - failed
          - refunded
          - draft
        amount:
          type: object
          properties:
            amount:
              type: integer
              description: Minor units.
            currency:
              type: string
        paid_at:
          type: string
          format: date-time
          nullable: true
    agreementPayload:
      type: object
      description: >-
        The data member of GET /api/v1/agreements/{id}, including the flat recipient fields
        recipients[].email and recipients[].name and field_values, a map of field_id to filled
        plain-text values. Nested recipients[].user and recipients[].contact objects are also
        included for backwards compatibility; the provider steers new integrations to the flat
        fields.
      properties:
        id:
          type: string
          format: uuid
        status:
          type: string
        recipients:
          type: array
          items:
            type: object
        field_values:
          type: object
  messages:
    invoiceCreated:
      name: invoice.created
      title: Invoice was created
      summary: Fires after POST /invoices.
      traits:
      - $ref: '#/components/messageTraits/signedEnvelope'
      payload:
        $ref: '#/components/schemas/envelope'
      examples:
      - name: invoiceCreated
        payload:
          event: invoice.created
          payload:
            id: 4a755746-ba45-4226-a669-aebc7ad3719c
            status: created
    invoiceSent:
      name: invoice.sent
      title: Invoice emailed to customer
      summary: Fires when delivery completes.
      traits:
      - $ref: '#/components/messageTraits/signedEnvelope'
      payload:
        $ref: '#/components/schemas/envelope'
    invoiceDue:
      name: invoice.due
      title: Invoice reached due status
      summary: >-
        Fires when status becomes due - either the scheduled job runs after sent (past due_at),
        or the invoice is sent already at or past due_at (immediate due).
      traits:
      - $ref: '#/components/messageTraits/signedEnvelope'
      payload:
        $ref: '#/components/schemas/envelope'
    invoicePaid:
      name: invoice.paid
      title: Payment successful
      summary: Fires after payment confirmation.
      description: >-
        One of the two events the provider recommends starting with - "Start with invoice.paid
        and invoice.failed - these are the most important for payment integrations."
      traits:
      - $ref: '#/components/messageTraits/signedEnvelope'
      payload:
        $ref: '#/components/schemas/envelope'
      examples:
      - name: invoicePaid
        payload:
          event: invoice.paid
          payload:
            id: 4a755746-ba45-4226-a669-aebc7ad3719c
            status: paid
            amount:
              amount: 15000
              currency: USD
            paid_at: '2025-01-20T14:30:00Z'
    invoiceFailed:
      name: invoice.failed
      title: Payment attempt failed
      summary: >-
        Fires after payment rejection. The invoice status becomes failed but the customer can
        retry payment using the same link.
      traits:
      - $ref: '#/components/messageTraits/signedEnvelope'
      payload:
        $ref: '#/components/schemas/envelope'
    invoiceCanceled:
      name: invoice.canceled
      title: Invoice was canceled
      summary: Fires after DELETE /invoices.
      traits:
      - $ref: '#/components/messageTraits/signedEnvelope'
      payload:
        $ref: '#/components/schemas/envelope'
    invoiceRefunded:
      name: invoice.refunded
      title: Invoice payment was refunded
      summary: Fires after a refund is processed.
      description: >-
        Note that no refund OPERATION exists in the REST API. This event is emitted for
        refunds performed outside the API surface.
      traits:
      - $ref: '#/components/messageTraits/signedEnvelope'
      payload:
        $ref: '#/components/schemas/envelope'
    agreementCreated:
      name: agreement.created
      title: Agreement was created
      summary: Fires after POST /agreements.
      traits:
      - $ref: '#/components/messageTraits/signedEnvelope'
      payload:
        $ref: '#/components/schemas/envelope'
    agreementSent:
      name: agreement.sent
      title: Agreement was sent to recipients
      summary: Fires when status changes to sent.
      traits:
      - $ref: '#/components/messageTraits/signedEnvelope'
      payload:
        $ref: '#/components/schemas/envelope'
    agreementSigned:
      name: agreement.signed
      title: Agreement was signed by a recipient
      summary: Fires when a recipient signs. Emitted once per signer.
      traits:
      - $ref: '#/components/messageTraits/signedEnvelope'
      payload:
        $ref: '#/components/schemas/envelope'
    agreementExecuted:
      name: agreement.executed
      title: Agreement was fully executed
      summary: Fires when all signers have signed.
      traits:
      - $ref: '#/components/messageTraits/signedEnvelope'
      payload:
        $ref: '#/components/schemas/envelope'
    webhookTest:
      name: webhook.test
      title: Test event
      summary: Fires when you trigger a test via POST /api/v1/webhooks/test.
      traits:
      - $ref: '#/components/messageTraits/signedEnvelope'
      payload:
        $ref: '#/components/schemas/envelope'
x-delivery:
  semantics: at-least-once
  duplicates: >-
    Documented as possible - "Webhooks may occasionally be sent more than once; use idempotency."
  retry_schedule:
  - attempt: 1
    delay: immediate
  - attempt: 2
    delay: ~1 minute
  - attempt: 3
    delay: ~5 minutes
  - attempt: 4
    delay: ~30 minutes
  - attempt: 5
    delay: ~2 hours
  after_exhaustion: >-
    The webhook is marked failed and the endpoint's failure_count is incremented. The provider
    recommends monitoring failure_count to detect integration issues.
  response_deadline: Return 200 within 5 seconds, then process asynchronously.
x-management:
  register: POST /api/v1/webhooks
  list: GET /api/v1/webhooks
  show: GET /api/v1/webhooks/{id}
  update: PUT|PATCH /api/v1/webhooks/{id}
  delete: DELETE /api/v1/webhooks/{id}
  test: POST /api/v1/webhooks/test
  disable: Set active to false rather than deleting.
  secret: >-
    A whsec_-prefixed signing secret is returned exactly once, in the create response, and
    cannot be retrieved afterwards.
  path_note: >-
    The prose documentation writes these paths as /api/v1/webhook_endpoints; the OpenAPI
    declares /api/v1/webhooks. The OpenAPI paths are used here. See
    conventions/agree-com-conventions.yml, documentation_defects.

Work with this as data

Every AsyncAPI spec here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for asyncapi

4 MCP tools reach this
  • find_asyncapisBrowse and filter every AsyncAPI spec in the catalog.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This AsyncAPI spec
curl "https://apis.io/api/v1/asyncapis/agree-com-webhooks-asyncapi"
All asyncapi
curl "https://apis.io/api/v1/asyncapis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.