Skip to main content

Fundamentals

Showpad communicates with your CRM connector via HTTPS requests and JSON responses. This page covers authentication, request payloads, and error handling.

TL;DR
  • Verify requests? Validate the x-showpad-signature-v1 header using HMAC-SHA256
  • Identify users? Every request includes showpadInfo with subdomain, username, and connector ID
  • Handle errors? Return appropriate HTTP codes and include errorMessage for debugging
  • Timeout limit? Respond within 15 seconds or Showpad displays an error

Authorization and security

Showpad signs every request with an HMAC-SHA256 signature. Your middleware must verify this signature to ensure requests are authentic and haven't been tampered with.

Signature headers

Every request includes two headers:

HeaderDescription
x-showpad-signature-timestampUnix epoch timestamp (seconds) when the request was sent
x-showpad-signature-v1Comma-separated Base64 HMAC-SHA256 signatures
x-showpad-signature-v1: FLauBV44UFC2oeY8AHcvGiUaL1Bx+FU5o+6ZM8KBdo0=,jR7SyZM0zpyYdOGZ1tOsv1av1RTmx3RzQyEKu7nHTUg=
x-showpad-signature-timestamp: 1668017345

Verification steps

  1. Check timestamp - Reject requests older than 5 minutes to prevent replay attacks
  2. Build signed payload - Concatenate: {request_body}.{timestamp}
  3. Compute HMAC - Generate HMAC-SHA256 using your Endpoint Signature Secret (from Admin App)
  4. Compare signatures - Request is valid if your hash matches any signature in the header

Get your signature secret

In the Admin App, go to Settings > Integrations > CRM > select your connector > copy the Endpoints Signature Secret.

Endpoint Signature Secret

Code examples

const crypto = require('crypto');

function verifySignature(req, secret) {
const timestamp = req.headers['x-showpad-signature-timestamp'];
const signatures = req.headers['x-showpad-signature-v1'].split(',');

// Step 1: Check timestamp (reject if older than 5 minutes)
const now = Math.floor(Date.now() / 1000);
if (now - parseInt(timestamp) > 300) {
return false;
}

// Step 2: Build signed payload
const body = JSON.stringify(req.body);
const signedPayload = `${body}.${timestamp}`;

// Step 3: Compute HMAC-SHA256
const expectedSignature = crypto.createHmac('sha256', secret).update(signedPayload).digest('base64');

// Step 4: Compare signatures
return signatures.includes(expectedSignature);
}
Important

Always verify signatures before processing requests. Skipping verification exposes your CRM to unauthorized access.

Identification

Every request includes a showpadInfo object in the POST body that identifies the organization and user:

{
"showpadInfo": {
"subdomain": "myorg",
"username": "user@company.com",
"crmInstanceId": "dsflkj2349fddd9asdf"
}
}
PropertyDescription
subdomainYour Showpad organization subdomain
usernameThe current user's email address in Showpad. Map this to the corresponding CRM user.
crmInstanceIdUnique identifier for this CRM connector. Useful if you have multiple connectors.
User mapping

We recommend requiring that Showpad user email addresses match exactly with email addresses in your CRM system. This simplifies user mapping and avoids lookup failures.

Response codes

Return standard HTTP status codes with your responses:

CodeWhen to use
200Request processed successfully
201Record created (e.g., activity logged)
4xxClient error (invalid request, unauthorized, etc.)
5xxServer error (CRM unavailable, internal error, etc.)

See HTTP response codes for more details.

Error handling

When your connector returns a non-success code, include an errorMessage to help users troubleshoot:

{
"errorMessage": "CRM System XYZ responded with a USER_UNAUTHORIZED code"
}

Showpad displays this message in the Admin App when available.

Common error scenarios

ScenarioRecommended response
User not found in CRM400 with "errorMessage": "No CRM user found for user@company.com"
CRM authentication failed401 with "errorMessage": "CRM authentication failed. Check API credentials."
Rate limited by CRM429 with "errorMessage": "CRM rate limit exceeded. Try again in X seconds."
CRM unavailable503 with "errorMessage": "CRM service unavailable"

Timeouts

Showpad times out requests after 15 seconds. To avoid timeout errors:

  • Cache frequently accessed CRM data
  • Use efficient CRM queries
  • Implement pagination for large result sets
  • Consider async processing for slow operations
Performance tip

Aim for response times under 2 seconds for the best user experience. Users searching for contacts expect near-instant results.

Next steps

Was this page helpful?