API

Webhooks

Anvil can POST to an endpoint on your server with a webhook. Add a webhook on your Organization Settings -> API Settings page.

Webhook Settings

When an action happens on Anvil's side, Anvil will post JSON to the URL you specify when setting up your webhook. The payload will look like the following:

{
  action: 'actionName',
  token: '38Gp2vP47zdj2WbP1sWdkO2pA7ySmjBk',
  data: 'RIaPFMKCP1Lqf8djqhG0uiN3UvrqQ5HgLxTBnigvSoQGwUeeRu...',
}
  • action is the name of the action that happened.
  • token is generated each time a new webhook is created from your Organization Settings page. It is a way for your server to make sure Anvil is making the request. Treat this as you would an API key. It is up to you to check that these match in your wehbook handler.
  • data is the actual payload of the webhook. It is encrypted with your organization's RSA key if you choose to create a keypair. Create a keypair on your Organization Settings -> API Settings page. If no keypair exists, data will be sent in a plaintext JSON string.

See our notes on encryption for information on creating a keypair and using it to decrypt data.

Webhook Actions

webhookTest

Called when the test button is clicked from the webhook settings UI.

Webhook Settings Test

{
  action: 'webhookTest',
  data: {...},
  token: '38Gp2vP47zdj2WbP1sWdkO2pA7ySmjBk'
}

weldCreate

Called when a workflow is created in the workflow builder.

{
  action: 'weldCreate',
  data: 'RIaPFMKCP1Lqf8djqhG0uiN3UvrqQ5HgLxTBnigvSoQGwUeeRu...',
  token: '38Gp2vP47zdj2WbP1sWdkO2pA7ySmjBk'
}

Once decrypted, it will have the following structure:

{
  eid: 'KtHa4IhKyoZO6hbQaQJK',
  name: 'New Office',
  slug: 'new-office',
  forges: [{
    eid: 'v9vlkzYU0e6IKpeYimIP',
    name: 'Virtual Office Setup'
    slug: 'new-office-admin'
  }, {
    eid: '0ZTRyrIlfcYsAo6A95Qk',
    name: 'Client Details',
    slug: 'new-office'
  }]
}

signerComplete

Called when a signer has finished signing their respective documents.

{
  action: 'signerComplete',
  data: 'RIaPFMKCP1Lqf8djqhG0uiN3UvrqQ5HgLxTBnigvSoQGwUeeRu...',
  token: '38Gp2vP47zdj2WbP1sWdkO2pA7ySmjBk'
}

Once decrypted, it will have the following structure:

{
  name: 'Sally Jones',
  email: 'sally@jones.net',
  status: 'completed',
  eid: '0ZTRyrIlfcYsAo6A95Qk',
  routingOrder: 1,
  weldData: {
    eid: '47zdj2WbP1sWdkO2pA7y',
  },
  documentGroup: {
    eid: '8jJ9yrIlfcYsAo6A95Qk',
    status: 'partial',
  },
  signers: [{
    name: 'Sally Jones',
    email: 'sally@jones.net',
    status: 'completed',
    eid: '0ZTRyrIlfcYsAo6A95Qk',
    routingOrder: 1,
  }, {
    name: 'Roscoe Jones',
    email: 'roscoe@jones.net',
    status: 'sent',
    eid: 'F6h77rIlfcYsAo6A95Qk',
    routingOrder: 2,
  }],
}

weldComplete

When an entire workflow is finished, it will call the webhook with the weldComplete action. It will only call this after all web forms in the workflow have been completed and all signers have signed their documents.

Note: the weldComplete webhook is called on test submissions. There will be an isTest field in the payload.

{
  action: 'weldComplete',
  data: 'RIaPFMKCP1Lqf8djqhG0uiN3UvrqQ5HgLxTBnigvSoQGwUeeRu...',
  token: '38Gp2vP47zdj2WbP1sWdkO2pA7ySmjBk'
}

Once decrypted, it will have the following structure:

{
  isComplete: true,
  isTest: false, // is this a test submission?
  eid: 'GHEJsCVWsR1vtCx3WtUI',
  documents: [{
    type: 'application/zip',
    url: 'http://localhost:3000/download/GHEJsCVWsR1vtCx3WtUI.zip',
  }],
  weld: {
    eid: 'KtHa4IhKyoZO6hbQaQJK',
    slug: 'new-office'
  },
  forges: {
    'new-office-admin': {
      eid: 'v9vlkzYU0e6IKpeYimIP',
      name: 'Virtual Office Setup'
    },
    'new-office': {
      eid: '0ZTRyrIlfcYsAo6A95Qk',
      name: 'Client Details'
    },
  },
  submissions: {
    'new-office-admin': {
      eid: 'sZXFCa4EF3cVRo0Qipqc',
      payload: {
        customerName: { value: 'SomeCo LLC', type: 'shortText' },
        // ...
      },
    },
    'new-office': {
      eid: 'xdwoukKDmOzLd5xbkApw',
      payload: {
        name: { value: 'Bobby Joe', type: 'shortText' },
        // ...
      },
    },
  },
}

Submission Payloads

Submission payloads will be an Object keyed by fieldId. Values will be an Object with a String type and value keys e.g.

{
  [fieldId]: {
    type: String,
    value: Any, // can be a string, number, object, etc depending on the type
  },
  ...other ids...
}

For example:

{
  email: {
    type: 'shortText',
    value: 'bobby@tables.com'
  },
  name: {
    type: 'fullName',
    value: {
      firstName: 'Bobby',
      mi: '',
      lastName: 'Tables'
    }
  },
  ...other ids...
}

Array types are represented similarly

{
  beneficiaries: {
    type: 'array',
    value: [{
      email: {
        type: 'shortText',
        value: 'bobby@tables.com'
      },
      name: {
        type: 'fullName',
        value: {
          firstName: 'Bobby',
          mi: '',
          lastName: 'Tables'
        }
      },
    }, ...]
  }
},

Submission Payload Types

// Strings
shortText: String
longText: String
email: String
ssn: String in format '123121234'
ein: String in format '121234567'
date: String in the format 'YYYY-MM-DD'
select: String ID of the option selected

// Numbers
number: Number
dollar: Number
integer: Number

// Bools
checkbox: Boolean

// Complex types

phone: Object {
  region: 'US',
  num: '555113333'
}

fullName: Object {
  firstName: 'Bobby',
  mi: 'W',
  lastName: 'Jones'
}

usAddress: Object {
  street1: '123 Main St',
  city: 'San Francisco',
  state: 'CA',
  zip: '94106',
  country: 'US' // ISO 3166 country code
}

file: Object {
  src: 'https://urlToFile',
  mimetype: 'image/png',
  name: 'cats.png'
}

// Arrays will have n Objects and will contain the types above
array: Array [{
  anId: ...one of the above...,
  anotherId: ...one of the above...,
  ...
}, {...}]