AI & automationOct 24, 202616 min read

Automate Email Signatures with an API and Webhooks: Onboarding, Offboarding and Failed-Install Alerts (2026)

The developer and IT automation guide to email signatures: API keys and scopes, onboarding flows for directory-synced and manual teammates, offboarding, alerts on failed installs and lost integrations, reliable webhook receivers, conversion sync to a CRM or warehouse, audit jobs and no-code options, with requests that match the documented Scribe API.

SG

Sophie Grant

Email Signature Specialist, Scribe

Automate Email Signatures with an API and Webhooks: Onboarding, Offboarding and Failed-Install Alerts (2026)

TL;DR: Use the API to pull and change state, and webhooks to react to events. With Scribe, the REST API at https://api.scribe-mail.com/v1 manages signatures, teammates, emails, Smart Fields, assignment, installs, campaigns and analytics with a scoped Bearer key, and signed webhooks (delivered through Svix) fire on teammate joins and departures, failed installs, lost integration access, campaign changes and attributed conversions. The three automations worth building first: install the right signature the day someone joins, alert IT the moment an install or integration breaks, and push signature-attributed conversions into your CRM or warehouse. Directory-synced teammates stay managed by Entra ID or Google Workspace; the API complements that sync rather than replacing it.

Last reviewed: October 2026. Covers Scribe API v1 and the webhook event catalog as documented at help.scribe-mail.com.

This guide is for IT automation engineers, platform teams and RevOps developers who want email signatures to follow the employee lifecycle without tickets. It covers authentication, onboarding and offboarding flows for directory-synced and manually managed teammates, failure alerts, conversion sync, audit jobs, and no-code options. Every request below matches the endpoints in Scribe's API reference and webhook event catalog. If you'd rather run the same operations by asking an AI assistant, see managing signatures from Claude or ChatGPT.

What can you automate with a signature API and webhooks?

Split the work by direction. Pull with the API when you need current state or want to change something. Subscribe to webhooks when you need to react the moment something happens.

JobAPI (pull or change)Webhook (push)
OnboardingPOST /v1/integrations/sync, POST /v1/emails/{id}/installteammate.created
OffboardingDELETE /v1/teammates/{id} (manually managed teammates)teammate.deleted
Deployment healthGET /v1/signature_installations?status=failed, GET /v1/integrationssignature.installation.failed, integration.access_lost
AssignmentPOST and PATCH /v1/signatures/{signature_id}/emails, POST /v1/signatures/{signature_id}/integration_entitiesNone
CampaignsPOST /v1/marketing_campaigns, /schedule, /pause, /resumecampaign.scheduled, .started, .paused, .resumed, .ended
AttributionGET /v1/analytics/views, POST /v1/analytics/eventsconversion.recorded, visitor.identified
Audit trailGET /v1/signatures, GET /v1/signatures/{id}/htmlsignature.published, integration.connected, integration.disconnected

There is no webhook for individual views or clicks. Engagement data comes from the analytics endpoints.

Get started with Scribe

Roll out signatures to your whole organization

Free 14-day trial — no credit card.

How do you authenticate and scope access?

Every request carries a workspace API key as a Bearer token (Scribe API authentication):

curl https://api.scribe-mail.com/v1/signatures \
  -H "Authorization: Bearer YOUR_API_KEY"
  • Create keys in the dashboard under Settings, API keys. The full key is shown once, so put it straight into a secret manager.
  • A key acts as the member who created it, with that member's role, narrowed by the scopes you grant, in one workspace.
  • Keys expire one year after creation. Put the expiry date in your secrets inventory and rotate before it.
  • Scopes use resource:action. Teammates, emails, signatures, Smart Fields, folders, assets and marketing campaigns each have read, write and delete scopes, such as teammates:write or signatures:read. Integrations and financial documents have only integrations:read and financial_documents:read.
  • Use one key per integration so you can revoke one without breaking the others.

Conventions: JSON over HTTPS, UUIDs for every resource, versioning in the path, and page-based lists with page and limit (default 50, maximum 100) plus a pagination object whose has_more tells you when to stop (pagination). Errors return an error object with type, code and message, and validation errors add a details array. A 403 means a missing scope or a feature your plan doesn't include. A resource in another workspace returns 404, never 403 (errors).

Scribe webhooks are part of the API, included in the Business and Enterprise plans and the 14-day trial. Only workspace owners and admins manage endpoints, from Settings, Webhooks, Manage webhooks, which opens a portal for endpoints, event subscriptions, delivery logs, replays, test sends and signing-secret rotation (Scribe webhooks overview).

How do you give a new hire the right signature on day one?

Most companies with 100 or more employees sync people from Microsoft Entra ID or Google Workspace. In that case, the directory creates the teammate and the API speeds up and verifies the rest. Teammates created by a directory integration can't be created or deleted through the API: those calls return 409 "Teammates managed by a directory integration" (create a teammate).

Directory-synced teammates

  1. Set assignment rules once. Give each signature Smart Field conditions, such as department, and turn on auto-assign for future teammates. New hires then match a signature as soon as they sync (signature assignment).
  2. Trigger a sync when your identity provider finishes creating the account, rather than waiting for the scheduled refresh. POST /v1/integrations/sync starts one background sync per activated teammates or Smart Fields integration and returns 202.
  3. React to teammate.created. It fires whether the person came from the dashboard, the API or a directory sync (webhook events).
  4. Install now. POST /v1/emails/{id}/install queues installation of the email's assigned, published signatures and returns 202 with the signatures and the API signature integrations it pushes them through. A 409 means there is no signature to install, usually because no rule matched yet.
  5. Verify. GET /v1/signature_installations?email_id=... returns each installation's status (installed, failed or uninstalled), email client, device and error code.
// Node 20+. Runs after your IdP provisions the account, and in the webhook worker.
const API = "https://api.scribe-mail.com/v1";
const headers = {
  Authorization: `Bearer ${process.env.SCRIBE_API_KEY}`,
  "Content-Type": "application/json",
};

// Step 2: ask Scribe to resync the team from its integrations now.
export async function resyncTeam() {
  const res = await fetch(`${API}/integrations/sync`, { method: "POST", headers });
  if (res.status === 409) throw new Error("Every integration lost its access: reconnect in the dashboard");
  return (await res.json()).data; // one running sync per integration
}

// Steps 3 and 4: called with a verified teammate.created event.
export async function onTeammateCreated(event) {
  const primary = event.emails.find((e) => e.primary) ?? event.emails[0];
  const res = await fetch(`${API}/emails/${primary.uuid}/install`, {
    method: "POST",
    headers,
    body: JSON.stringify({}),
  });
  if (res.status === 409) {
    // No signature to install: no assignment rule matched this person.
    await itsm.createTask({ title: `No signature rule matched ${primary.address}` });
    return;
  }
  const { data } = await res.json(); // status: "queued"
  await jobs.schedule("check-install", { emailId: data.email_id }, { delayMinutes: 15 });
}

// Step 5: confirm the result.
export async function checkInstall({ emailId }) {
  const res = await fetch(`${API}/signature_installations?email_id=${emailId}`, { headers });
  const { data } = await res.json();
  return data.map((i) => ({ client: i.email_client, status: i.status, error: i.error_code }));
}

The webhook payload's email uuid is the same ID the API uses, so no lookup is needed. Scribe states that every resource reference in an event is a UUID the REST API serves (webhook events).

If a new hire's title or phone is wrong, fix it in the directory or HRIS. Directory data flows one way into Scribe, and the API doesn't write back to synced directory fields (API use cases). The Handbook guides to Entra ID attributes and HRIS sync cover the source side.

Manually managed teammates

Contractors, a subsidiary outside your tenant, or a workspace without directory sync can be managed directly. This is the programmatic version of the manual form and CSV upload.

# 1. Look up the Smart Field IDs you will fill
curl https://api.scribe-mail.com/v1/smart_fields \
  -H "Authorization: Bearer YOUR_API_KEY"

# 2. Create the teammate with their values (returns data.id and data.emails[].id)
curl https://api.scribe-mail.com/v1/teammates \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "teammate": {
      "email": "jordan@acme.com",
      "smart_fields": [
        { "smart_field_id": "8e0d4b1a-2c3d-4f5a-9b6d-7c2e9a3f1c2e", "value": "Account Executive" },
        { "smart_field_id": "a1b2c3d4-5e6f-4a8b-9c0d-1e2f3a4b5c6d", "value": "+1 555 0142" }
      ]
    }
  }'

# 3. Assign the signature to the new email
curl https://api.scribe-mail.com/v1/signatures/SIGNATURE_ID/emails \
  -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "email_ids": ["EMAIL_ID"] }'

# 4. Install it for that email now
curl https://api.scribe-mail.com/v1/emails/EMAIL_ID/install \
  -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

When the person's role changes, PATCH /v1/teammates/{id} with a teammate.smart_fields array updates their values. An unknown Smart Field returns 422.

How do you offboard signatures automatically?

Directory-synced: deactivating someone's license in Microsoft Entra ID or Google Workspace removes their signature from Scribe and removes them from your subscription automatically (Scribe billing). Your job is to mirror the departure elsewhere. Subscribe to teammate.deleted and store what you need from the payload, because it's the last chance to read the person's identifiers; the API can't return them once they are gone (webhook use cases).

// Called with a verified teammate.deleted event.
async function onTeammateDeleted(event) {
  const primary = event.emails.find((e) => e.primary) ?? event.emails[0];
  await directory.markOffboarded({
    teammateUuid: event.teammate.uuid,
    email: primary.address,
    offboardedAt: event.occurred_at,
  });
}

Manually managed: delete the teammate to stop their signature deploying. DELETE /v1/teammates/{id} returns 204. To remove only an alias, DELETE /v1/emails/{id}; a primary email can't be deleted (422).

curl https://api.scribe-mail.com/v1/teammates/TEAMMATE_ID \
  -X DELETE \
  -H "Authorization: Bearer YOUR_API_KEY"

Departures also lower cost: in Scribe a paid user is a teammate assigned to a signature, billed on primary addresses, not aliases (Scribe billing).

How do you alert IT when a signature install fails?

Subscribe one endpoint to signature.installation.failed and integration.access_lost. The first names the mailbox, the signature, the integration and an error_code. Known codes are user_not_found, forbidden, unauthorized_client, channel_not_found, signature_too_long and multi_signatures_not_supported, and new ones can be added (webhook events). The second fires when Scribe loses access to a connected integration, which pauses installs and syncs through it, and includes a reconnect_url.

const ROUTES = {
  user_not_found: "it-identity",        // mailbox deleted or renamed
  forbidden: "it-identity",             // scopes or admin consent
  unauthorized_client: "it-identity",
  signature_too_long: "brand-ops",      // template problem
  multi_signatures_not_supported: "brand-ops",
};

async function onInstallationFailed(event) {
  const { email, signature, integration, error_code } = event;
  const queue = ROUTES[error_code] ?? "it-helpdesk"; // keep a default for new codes
  await itsm.createTask({
    queue,
    title: `Signature install failed for ${email.address}`,
    body: `Template ${signature.name} (${signature.kind}) via ${integration.kind}: ${error_code}`,
  });
}

async function onIntegrationAccessLost(event) {
  const { integration, error_message, reconnect_url } = event;
  await pager.trigger({
    severity: integration.category === "signatures" ? "error" : "warning",
    summary: `Scribe lost access to ${integration.name}: ${error_message}`,
    link: reconnect_url,
  });
}

Both events fire on the transition into failure, once, not daily while the problem persists. A reconnect re-arms integration.access_lost, and a new failure after a successful reinstall fires again. Track open items on your side, and run a daily sweep as a backstop:

curl "https://api.scribe-mail.com/v1/signature_installations?status=failed&limit=100" \
  -H "Authorization: Bearer YOUR_API_KEY"

The Gmail signature_too_long case is covered in Gmail "signature too long".

How do you receive webhooks reliably?

Scribe webhooks are delivered by Svix and follow the Standard Webhooks signing scheme. Every request carries svix-id, svix-timestamp and svix-signature headers, and the signing secret is in the webhook portal (webhooks overview). Verify against the raw body, acknowledge fast, then queue the work:

import express from "express";
import { Webhook } from "svix";

const app = express();
const wh = new Webhook(process.env.SCRIBE_WEBHOOK_SECRET);

// Verification needs the raw body, so do not parse JSON before it.
app.post("/webhooks/scribe", express.raw({ type: "application/json" }), async (req, res) => {
  let event;
  try {
    event = wh.verify(req.body, req.headers);
  } catch {
    return res.sendStatus(400);
  }
  res.sendStatus(200);
  // svix-id is stable across retries of the same message: use it to deduplicate.
  await queue.add("scribe-event", { id: req.headers["svix-id"], event });
});
  • Respond within 15 seconds with any 2xx. Anything else, including a timeout, is a failure.
  • Retries use exponential backoff over roughly a day. Endpoints that keep failing are eventually disabled; re-enable them and replay missed deliveries from the portal.
  • Delivery is at least once. Deduplicate on svix-id.
  • Order isn't guaranteed. Sequence on the payload's occurred_at.
  • HTTPS only, reachable from the internet. For IP allowlisting, use the source addresses Svix publishes.
  • Ignore unknown types and fields. New events and fields are added over time.

How do you push signature conversions to a CRM or warehouse?

If you use Scribe conversion tracking, conversion.recorded fires for every attributed, deduplicated conversion with the teammate, signature template, link, email and campaign behind it, as UUIDs (empty strings when unresolved). visitor.identified fires the first time a signature-attributed visitor is identified, which is the moment to create the contact record (webhook events).

async function onConversionRecorded(event, deliveryId) {
  const { visitor, attribution } = event;
  await crm.upsertOpportunity({
    externalId: event.event_id ?? deliveryId, // event_id can be null
    contactExternalId: visitor.user_id,
    name: event.name,
    amount: event.value,
    currency: event.currency,
    source: "Email signature",
    ownerUuid: attribution.teammate_uuid || null,
    campaignUuid: attribution.marketing_campaign_uuid || null,
  });
}

Two API calls complete the picture. Record trusted revenue from your backend with POST /v1/analytics/events, passing the click_id captured from the landing URL or the identified user_id, and an event_id so a repeat within 24 hours is recorded once:

curl https://api.scribe-mail.com/v1/analytics/events \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "event": {
      "name": "purchase",
      "value": 149.0,
      "currency": "USD",
      "event_id": "order_8821",
      "user_id": "user_42"
    }
  }'

And export engagement daily with GET /v1/analytics/views, grouped by signature_template, marketing_campaign, teammate, anchor (link) or country; each breakdown row carries view_count, click_count and clickthrough_rate:

curl "https://api.scribe-mail.com/v1/analytics/views?group_by=marketing_campaign&start_date=2026-09-01&end_date=2026-09-30&limit=100" \
  -H "Authorization: Bearer YOUR_API_KEY"

Scribe has no native HubSpot or Salesforce sync, so these webhooks and exports are the route into a CRM. The marketing side, including UTMs and campaign reporting, is in the Handbook guide to banner campaigns and attribution and in tracking banner clicks in HubSpot and Salesforce.

How do you automate signature audits and keep an audit trail?

A nightly job answers the questions an auditor or security review asks:

  1. GET /v1/signatures: which templates exist, when each was last published, and whether installation is activated.
  2. GET /v1/signatures/{signature_id}/emails: who each one reaches, with the source of each assignment, such as a manual pick or a directory group.
  3. GET /v1/signature_installations?status=failed: mailboxes where installation failed, with the error code.
  4. GET /v1/integrations: each integration's status (active or error), the error message, and a dashboard_url to fix it, since the API never runs OAuth.
  5. GET /v1/signatures/{id}/html?email_id=...: the real rendered HTML a given recipient's emails carry, for evidence files.

For a change history, subscribe one endpoint to every event type and write each payload, with its svix-id and svix-timestamp, to append-only storage. That gives you who published which signature and when, which integrations were connected or removed, and when each teammate arrived and left (webhook use cases). Scribe also sells an audit log add-on for actions inside the workspace (Scribe plans). Put the audit cadence in your email signature policy.

Can you manage signature templates as code?

Yes. POST /v1/signatures and PATCH /v1/signatures/{id} stage content as a draft, GET /v1/signatures/{id}/preview renders it with placeholder values, and POST /v1/signatures/{id}/publish makes it live. Content is a block tree; fetch GET /v1/content_schema before writing one, because an invalid tree returns 422 naming each bad field (signature content). Keep the JSON in a repository, review changes as pull requests, and publish from CI, with a staged rollout as described in the rollout playbook. Reply and internal variants have their own endpoints and require an active Microsoft 365 signatures integration.

Can you do this without writing code?

Yes, for notifications and simple syncs. Zapier, Make and n8n each give you a catch-hook URL you can register as a Scribe webhook endpoint (webhook use cases):

  1. Create a webhook trigger in your automation tool and copy its URL.
  2. In Scribe, open Settings, Webhooks, Manage webhooks, add the URL and subscribe it to the events the workflow needs.
  3. Send a test delivery from the portal so the tool learns the payload shape.
  4. Route on type and map fields such as email.address or value into the action.

Most automation platforms don't verify webhook signatures, so anyone who learns the URL can post to it. Use these endpoints for low-stakes alerts, and add a verification step before anything writes to a system of record.

What can't the API do?

  • Connect or configure integrations. Integrations are set up in the dashboard with OAuth. A key can read them but can't activate, edit or remove them (authentication).
  • Write back to the directory. Data flows one way from Entra ID or Google Workspace into Scribe.
  • Create or delete directory-managed teammates. Those calls return 409.
  • Stream clicks. There is no click webhook; poll the analytics endpoints.
  • Variants without Microsoft 365. Reply and internal variant writes return 409 variants_unavailable without an active Microsoft 365 signatures integration (tools reference).

Which automation should you build first, and how do you test it?

Build in order of risk removed per hour of work:

  1. Failure alerts. Two webhook events and a ticketing call. They catch revoked integrations and broken mailboxes that otherwise go unnoticed for weeks.
  2. Onboarding install and verification. Assignment rules plus teammate.created, install now, and a check fifteen minutes later. New hires stop emailing customers with a blank signature.
  3. Offboarding mirror. teammate.deleted into your ITSM or directory records, so access reviews have a timestamp.
  4. Conversion sync and exports. Worth it once marketing runs banner campaigns and wants pipeline numbers.
  5. Templates as code. For teams that already review infrastructure changes in pull requests.

Test each one before it touches everyone. Use the webhook portal's test deliveries to exercise your receiver and its signature check, point new automations at a pilot group first, and keep a separate key for the test so you can delete it when you're done. A key belongs to one workspace, so a separate workspace gives you a full sandbox if your plan allows more than one.

Where does Scribe fit?

Scribe's REST API, hosted MCP server and open-source CLI expose the same operations, and webhooks report what changed, so a workflow can start as a chat prompt, become a CLI script, and end up as a service on the API. The developer overview is at Scribe API, with workflows in the API use cases and webhook use cases. Pricing is per user, with Enterprise pricing from 100 users and a 14-day trial (pricing). For the product-side view of automation, see email signature automation best practices.

Frequently asked questions

Does Scribe have an API for email signatures?

Yes. Scribe's REST API at https://api.scribe-mail.com/v1 manages signatures, variants, assignment, installs, teammates, emails, Smart Fields, folders, assets, marketing campaigns, integrations (read only), analytics, conversion events and visitors. It uses JSON over HTTPS, UUIDs and workspace API keys sent as Bearer tokens.

Which webhook events does Scribe send?

conversion.recorded, visitor.identified, signature.published, signature.installation.failed, teammate.created, teammate.deleted, five campaign events (scheduled, started, paused, resumed, ended), integration.connected, integration.access_lost and integration.disconnected. There is no webhook for individual views or clicks.

Can I create teammates through the API if we sync from Entra ID or Google Workspace?

No. Teammates managed by a directory integration return 409 on create and delete. Let the directory create them, trigger POST /v1/integrations/sync to pick them up immediately, then install with POST /v1/emails/{id}/install. Use POST /v1/teammates for people you manage by hand.

How do I get alerted when a signature fails to install?

Subscribe to the signature.installation.failed webhook. It fires once per failure with the mailbox, signature, integration and an error_code such as user_not_found, forbidden or signature_too_long. Pair it with integration.access_lost, and run a daily GET /v1/signature_installations?status=failed as a backstop.

How are Scribe webhooks signed and retried?

Deliveries come from Svix with svix-id, svix-timestamp and svix-signature headers, following the Standard Webhooks scheme. Respond 2xx within 15 seconds. Failures are retried with exponential backoff over roughly a day, delivery is at least once, and order isn't guaranteed, so deduplicate on svix-id and sequence on occurred_at.

How long do Scribe API keys last, and what can they access?

Keys expire one year after creation. Each key acts as the member who created it, in one workspace, narrowed by resource:action scopes such as teammates:write or signatures:read. Integrations and financial documents are read only. Store keys in a secret manager and use one key per integration.

Can I send signature conversions to HubSpot or Salesforce?

Not through a native integration. Subscribe to conversion.recorded, which carries the teammate, signature, link and campaign behind each attributed conversion, and write it to the CRM with your own endpoint or with Zapier, Make or n8n. Engagement totals can be exported daily from GET /v1/analytics/views.

Do I need a developer to use Scribe webhooks?

Not for simple workflows. Register a Zapier, Make or n8n catch-hook URL in Settings, Webhooks, Manage webhooks, send a test delivery, and map the fields. Those tools usually don't verify signatures, so keep them for notifications and verify before writing to a system of record.

Get started with Scribe

Roll out signatures to your whole organization

Free 14-day trial — no credit card.

More guides in this cluster

Stripe email signature – Patrick Collison
Notion email signature – Camille Ricketts

Start your 14-day
free trial

Join 10,000+ companies using Scribe to power 15 million daily brand impressions

No card required. All features. Unlimited users.

Nike email signature – Greg Hoffman
Headspace email signature – Andy Puddicombe