Back to APIs

Manage payments, expenses, teams and more with Brex.

Using the Brex API with Trigger.dev

You can use Trigger.dev with any existing Node SDK or even just using fetch. Using io.runTask makes your Brex background job resumable and appear in our dashboard.

Use io.runTask() and the official SDK or fetch.

Use our HTTP endpoint to subscribe to webhooks

Example code using Brex

Below are some working code examples of how you can use Brex with Trigger.dev. These samples are open source and maintained by the community, you can copy and paste them into your own projects.

1
import { TriggerClient } from "@trigger.dev/sdk";
2
import { createHmac, timingSafeEqual } from "crypto";
3
import { Slack } from "@trigger.dev/slack";
4
5
const slack = new Slack({ id: "slack" });
6
7
// API key Docs: https://developer.brex.com/docs/authentication/
8
// Sign in to dashboard.brex.com as an account admin.
9
// Go to Developer > Settings.
10
// Click Create Token.
11
// Add a name for your token and choose level of data access you need for your app; then click Create Token.
12
13
// Webhooks docs: https://developer.brex.com/openapi/webhooks_api/
14
15
// Create an HTTP Endpoint, with the Brex details
16
const brex = client.defineHttpEndpoint({
17
id: "brex",
18
source: "brex.com",
19
icon: "brex",
20
verify: async (request) => {
21
const webhook_id = request.headers.get("Webhook-Id");
22
const webhook_signature = request.headers.get("Webhook-Signature");
23
const webhook_timestamp = request.headers.get("Webhook-Timestamp");
24
const body = await request.text();
25
26
if (!webhook_id || !webhook_signature || !webhook_timestamp) {
27
return { success: false, reason: "Missing brex headers" };
28
}
29
30
const signed_content = `${webhook_id}.${webhook_timestamp}.${body}`;
31
const passed_signatures = webhook_signature
32
.split(" ")
33
.map((sigString) => sigString.split(",")[1]);
34
35
const response = await fetch(
36
`https://platform.brexapis.com/v1/webhooks/secrets`,
37
{
38
headers: {
39
"Content-Type": "application/json",
40
Authorization: `Bearer ${process.env.BREX_API_KEY}`,
41
},
42
}
43
);
44
45
const data = await response.json();
46
const secrets = data.map(
47
(secretObj: { secret: string; status: string }) => secretObj.secret
48
);
49
50
for (const secret of secrets) {
51
const base64DecodedSecret = Buffer.from(secret, "base64");
52
const hmac = createHmac("sha256", base64DecodedSecret);
53
const computed_signature = hmac.update(signed_content).digest();
54
55
for (const passed_signature of passed_signatures) {
56
const decodedPassedSignature = Buffer.from(passed_signature, "base64");
57
58
if (timingSafeEqual(computed_signature, decodedPassedSignature)) {
59
return { success: true };
60
}
61
}
62
}
63
64
return { success: false, reason: "Invalid brex signature" };
65
},
66
});
67
68
// The job sends a Slack message when a user is updated
69
client.defineJob({
70
id: "http-brex",
71
name: "HTTP Brex",
72
version: "1.0.0",
73
enabled: true,
74
// Create a trigger from the HTTP endpoint
75
trigger: brex.onRequest(),
76
integrations: {
77
slack,
78
},
79
run: async (request, io, ctx) => {
80
const body = await request.json();
81
await io.logger.info(`Body`, body);
82
83
switch (body.event_type) {
84
case "USER_UPDATED": {
85
await io.slack.postMessage("user-updated", {
86
channel: process.env.SLACK_CHANNEL!,
87
text: `User updated:\nUser id: ${
88
body.user_id
89
}\nUpdated attributes: ${body.updated_attributes.join(", ")}`,
90
});
91
break;
92
}
93
}
94
},
95
});