Partners are able to register multiple webhook subscriptions per account; these subscriptions must be unique by URL per partner. We do not currently support scoping per webhook subscription, so all webhook events will be sent to every endpoint the partner has registered. Subscription to specific webhook scopes is coming soon.
Follow the steps below to set up webhooks for your Basic Capital integration.
Webhooks do not contain any details on the triggered event. Instead, they provide the event type, entity ID, and information about the owner of the data. Together, these provide the information necessary in order to pull the event details from Basic Capital.
Webhook events will be in the following format:
POST /your/configured/webhook/endpoint
X-BC-Webhook-Validation-Token: "sample_validation_token"
{
"owner_uuid": "string",
"scope": "PARTNER | COMPANY | EMPLOYEE",
"object_uuid": "string",
"event_type": "EventType",
"timestamp": "string",
"request_id": "string"
}
Field definitions:
| Field | Description |
|---|---|
owner_uuid | The entity this event belongs to; pass this in the X-Identity-Uuid header when requesting the data |
scope | The identity type this event belongs to; pass this in the X-Identity-Type header when requesting the data |
object_uuid | The actual object the event is referencing; used to fetch specific event |
event_type | The type of event that occurred; we indicate which endpoints owns each event type below |
timestamp | When the communication was sent, not when the event occurred. Used for authenticating the webhook request |
request_id | Unique ID for each webhook message request |
While it is not strictly required, we strongly recommend that partners implement verification on incoming webhooks. Each webhook will carry the following JWT header:
X-BC-Webhook-Validation-Token: "sample_validation_jwt"
Verify as follows:
- Fetch Basic Capital's public key via
GetWebhookValidationContext(gRPC). We recommend caching this value. - Use the public key to decode the JWT, which will have the following format
{ "requestId": "string", "timestamp": "string" } - Verify the
timestamp, which will be in epoch milliseconds. Reject requests older than 5 minutes. - Verify the
requestIdis unique. - Verify
timestampandrequestIdvalues match what is in the request body.
- Register a new webhook at
CreateWebhookSubscription(gRPC) - On registration, Basic Capital will send a webhook message to the url with event type
VERIFY_WEBHOOK. This endpoint must return a 200, or the subscription will not be created.
Webhooks will be created if the initial VERIFY_WEBHOOK event returns a 200. However, if a webhook endpoint begins to fail consistently, it will eventually be deactivated. We recommend that you remove old webhooks for clarity; this will help Basic Capital give the best support for your integration. Webhook subscriptions can be paused, reactivated, or deleted via SetWebhookSubscriptionStatus (gRPC).
You can list your current webhooks at any time at ListWebhookSubscriptions (gRPC).
New webhook event types may be added in the future. We recommend implementations ignore unknown event types instead of erroring, to ensure they remain compatible.
| Event Type | Description | Scope | Endpoint |
|---|---|---|---|
VERIFY_WEBHOOK | Initial verification. Must return a 200. | n/a | n/a |
ALERT_ACTION_REQUIRED | Required action in Basic Capital dashboard | COMPANY or EMPLOYEE | Log into Basic Capital |
ALERT_INFORMATIONAL | New alert, no action required | COMPANY or EMPLOYEE | Log into Basic Capital |
EMPLOYEE_STATUS_CHANGE | Change to employee's status | COMPANY | GetEmployeeDetails |
EMPLOYEE_ONBOARDING_STATUS_CHANGE | Change to employee's onboarding progress | EMPLOYEE | GetEmployeeOnboardingStatus |
CONTRIBUTION_CONFIG_UPDATED | Update to employee's contributions | EMPLOYEE | GetEmployeeContributionRates |
COMPANY_ONBOARDING_STATUS_CHANGE | Async updates during company onboarding | COMPANY | GetCompanyOnboardingStatus |
PLAN_CONFIGURATION_STATUS_CHANGE | Updates to plan configuration status | COMPANY | GetCompanyOnboardingStatus |
Create a new webhook subscription. Will fail if the partner already has a subscription with this URL.
service PartnerIngressService {
rpc CreateWebhookSubscription(CreateWebhookSubscriptionRequest) returns (CreateWebhookSubscriptionResponse);
}
message CreateWebhookSubscriptionRequest {
string url = 1;
}
message CreateWebhookSubscriptionResponse {
WebhookSubscription webhook_subscription = 1;
}Data types: WebhookSubscription
service PartnerIngressService {
rpc GetWebhookSubscription(GetWebhookSubscriptionRequest) returns (GetWebhookSubscriptionResponse);
}
message GetWebhookSubscriptionRequest {
string uuid = 1;
}
message GetWebhookSubscriptionResponse {
optional WebhookSubscription webhook_subscription = 1;
}Data types: WebhookSubscription
Returns all subscriptions for a partner. Includes paused subscriptions.
service PartnerIngressService {
rpc ListWebhookSubscriptions(ListWebhookSubscriptionsRequest) returns (ListWebhookSubscriptionsResponse);
}
message ListWebhookSubscriptionsRequest {}
message ListWebhookSubscriptionsResponse {
repeated WebhookSubscription webhook_subscriptions = 1;
}Data types: WebhookSubscription
Update the URL for a subscription. Errors if the URL is already registered.
service PartnerIngressService {
rpc UpdateWebhookSubscription(UpdateWebhookSubscriptionRequest) returns (UpdateWebhookSubscriptionResponse);
}
message UpdateWebhookSubscriptionRequest {
string uuid = 1;
string url = 2;
}
message UpdateWebhookSubscriptionResponse {
WebhookSubscription webhook_subscription = 1;
}Data types: WebhookSubscription
Pause, reactivate, or delete a subscription.
service PartnerIngressService {
rpc SetWebhookSubscriptionStatus(SetWebhookSubscriptionStatusRequest) returns (SetWebhookSubscriptionStatusResponse);
}
message SetWebhookSubscriptionStatusRequest {
enum StatusUpdate {
UNKNOWN_STATUS_UPDATE = 0;
REACTIVATE = 1;
PAUSE = 2;
DELETE = 3;
}
string uuid = 1;
StatusUpdate status_update = 2;
}
message SetWebhookSubscriptionStatusResponse {
WebhookSubscription webhook_subscription = 1;
}Data types: WebhookSubscription
Fetch the public key for webhook signature validation. Cache this value.
service PartnerIngressService {
rpc GetWebhookValidationContext(GetWebhookValidationContextRequest) returns (GetWebhookValidationContextResponse);
}
message GetWebhookValidationContextRequest {}
message GetWebhookValidationContextResponse {
string public_key = 1;
}Partner-facing webhook subscription. DEV_TEST is surfaced as ACTIVE. DELETED is only ever returned in the immediate response to a SetWebhookSubscriptionStatus delete; Get/List exclude DELETED subscriptions.
message WebhookSubscription {
enum Status {
UNKNOWN_STATUS = 0;
ACTIVE = 1;
ERRORED = 2;
PAUSED = 3;
DELETED = 4;
}
string uuid = 1;
string url = 2;
Status status = 3;
optional string notes = 4;
}