Skip to main content
Job: make a workflow run when the business event happens.

Webhook: enrich inbound leads

The incoming JSON body becomes the play input.
{
  "email": "jane@example.com",
  "company_domain": "example.com",
  "source": "hubspot"
}
This workflow receives an inbound lead payload.
import { definePlay } from 'deepline';

type InboundLead = {
  email: string;
  company_domain?: string;
};

export default definePlay('inbound-lead', async (ctx, input: InboundLead) => {
  const domain = input.company_domain ?? input.email.split('@')[1] ?? '';
  const company = await ctx.tools.execute({
    id: 'company_context',
    tool: 'test_rate_limit',
    input: { key: domain },
    description: 'Add company context before routing the inbound lead.',
  });

  return { email: input.email, domain, company_status: company.status };
}, {
  webhook: {
    hmac: {
      secretEnv: 'HUBSPOT_WEBHOOK_SECRET',
      header: 'x-hubspot-signature-v3',
      algorithm: 'sha256',
    },
  },
});
Start without HMAC while testing if your source allows it:
import { definePlay } from 'deepline';

export default definePlay('inbound-lead', async (_ctx, input: { email: string }) => {
  return { email: input.email };
}, {
  webhook: {},
});
Add HMAC before production if the sender supports signatures.

Schedule: refresh accounts

This workflow refreshes accounts on a schedule.
import { definePlay } from 'deepline';

type Account = {
  domain: string;
};

export default definePlay('nightly-account-refresh', async (ctx, input: { accounts: Account[] }) => {
  const rows = await ctx
    .dataset('accounts', input.accounts)
    .withColumn('company_signal', (account, rowCtx) =>
      rowCtx.tools.execute({
        id: 'company_signal',
        tool: 'test_rate_limit',
        input: { key: account.domain },
        description: 'Refresh one account signal.',
      }),
    )
    .run({ key: 'domain' });

  return { rows };
}, {
  cron: {
    schedule: '0 9 * * *',
    timezone: 'America/New_York',
  },
});
Use this when freshness matters more than a human clicking run.

Activation boundary

Trigger declarations are inert while the play is a draft. Check, then publish:
deepline plays check docs-examples/sdk-v2/nightly-account-refresh.play.ts
deepline plays publish docs-examples/sdk-v2/nightly-account-refresh.play.ts
Then run a manual test before waiting for the schedule:
deepline plays run docs-nightly-account-refresh --input '{"accounts":[]}' --watch
Manual tests prove the play logic before you wait for the next event.