Getting Started
This page will help you get started with Sure Send. You'll be up and running in a jiffy!
Getting Started with Sure Send CRM Partner API
Welcome to the Sure Send CRM Partner API! This guide will help you get up and running quickly with our API to manage contacts, track events, and integrate with your applications.
Prerequisites
Before you begin, you'll need:
- A Sure Send CRM account with API access
- An API token (generated from Settings > API Tokens in your dashboard)
- Basic knowledge of REST APIs and HTTP requests
Authentication
The Partner API uses Bearer token authentication. Include your API token in the Authorization header of every request:
curl https://api.suresend.ai/api/partner/people \
-H "Authorization: Bearer YOUR_API_TOKEN"Quick Start: Create Your First Contact
Let's create a contact in your CRM:
curl -X POST https://api.suresend.ai/api/partner/people \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"firstName": "Jane",
"lastName": "Doe",
"emails": [
{
"value": "[email protected]",
"isPrimary": true
}
],
"phones": [
{
"value": "+1-555-1234",
"type": "mobile",
"isPrimary": true
}
],
"tags": ["new-lead"]
}'Response:
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"firstName": "Jane",
"lastName": "Doe",
"name": "Jane Doe",
"emails": [...],
"phones": [...],
"tags": ["new-lead"],
"createdAt": "2025-10-16T12:00:00Z"
}Key Concepts
People (Contacts)
People are the core entity in the CRM. They represent your contacts, leads, and customers.
Common Operations:
GET /api/partner/people- List all contactsGET /api/partner/people/{id}- Get a specific contactPOST /api/partner/people- Create a new contactPUT /api/partner/people/{id}- Update a contactDELETE /api/partner/people/{id}- Delete a contact
Events
Events track all interactions and activities with your contacts (page views, property views, form submissions, etc.).
Example: Track a page view
curl -X POST https://api.suresend.ai/api/partner/events \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "page_view",
"personId": "123e4567-e89b-12d3-a456-426614174000",
"pageUrl": "https://example.com/properties/123",
"pageTitle": "Beautiful 3BR Home"
}'Notes & Tasks
Keep detailed records and create follow-ups:
Add a note:
curl -X POST https://api.suresend.ai/api/partner/notes \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"personId": "123e4567-e89b-12d3-a456-426614174000",
"subject": "Follow-up call",
"body": "Discussed property requirements and budget."
}'Create a task:
curl -X POST https://api.suresend.ai/api/partner/tasks \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"personId": "123e4567-e89b-12d3-a456-426614174000",
"name": "Follow up on property inquiry",
"type": "call",
"dueDateTime": "2025-10-20T14:00:00Z"
}'Rate Limiting
Rate limits are per team, not per API token. Every API key on a team draws on the same allowance, so creating more keys doesn't raise the limit.
- Default: 300 requests/minute
- With System ID: 600 requests/minute when you send a registered, active System ID in the
X-System-Idheader. Register your system to double your limit - Counted per resource: Each resource (for example
/people,/tasksor/calls) has its own counter. 300 requests to/peopleand 300 to/tasksin the same minute are both allowed - Per System ID: Requests with a System ID are counted separately from requests without one, and separately for each System ID
- Window: A fixed 60-second window that starts with the first request counted in it
- Custom limits: Sure Send staff can set a different limit for a team, a System ID or an individual API token, for all endpoints or for specific endpoints or HTTP methods. A custom limit replaces the default for the requests it covers
- Every response includes rate limit headers:
X-RateLimit-Limit- Maximum requests allowedX-RateLimit-Remaining- Requests remainingX-RateLimit-Reset- Window duration in secondsX-RateLimit-Context- Which limit was applied (token:default,api_system:default, or the custom limit's context)
Example rate limit headers:
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 598
X-RateLimit-Reset: 60
X-RateLimit-Context: api_system:default
When you exceed a rate limit, you'll receive a 429 Too Many Requests response with a Retry-After header and X-Throttle-Reason: rate_limit.
Need a higher limit? Register a System ID first: that alone takes you from 300 to 600 requests/minute. If you still need more, email [email protected] with your team name, your System ID, the endpoints you call, and the requests per minute you need.
Not every 429 is a rate limit. Each API token also has a circuit breaker: after 20 consecutive failed requests (any non-2xx other than 404 or 429, counted only on requests that reached the endpoint), the token is paused for 5 minutes and every request gets a 429 with X-Throttle-Reason: circuit_breaker, a code of circuit_breaker_open, and a lastFailure naming the call that was failing. Raising your rate limit will not help in that case; fix the failing call and wait out Retry-After. The Rate Limiting section of the API reference shows the full response.
Tip: Register a System ID to get 600 requests/minute and per-system usage tracking.
Webhooks
Webhooks allow you to receive real-time notifications when events occur in your CRM.
Set up a webhook:
curl -X POST https://api.suresend.ai/api/partner/webhooks \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Contact Sync Webhook",
"url": "https://your-app.com/webhooks/crm-events",
"events": ["peopleCreated", "peopleUpdated", "peopleStageUpdated"]
}'Important: The response includes a secret_key which is only shown once. Store it securely - you'll need it to verify webhook signatures.
Verify webhook signatures:
require 'openssl'
require 'rack/utils'
def verify_webhook(request, secret_key)
# The header value is "sha256=<hex digest>"
received_signature = request.headers['X-Webhook-Signature'].to_s
body = request.raw_post # raw bytes, before any JSON parsing
computed_signature = "sha256=#{OpenSSL::HMAC.hexdigest('SHA256', secret_key, body)}"
Rack::Utils.secure_compare(computed_signature, received_signature)
endFailed deliveries are retried up to 5 times over about 16 minutes. See the Webhooks Guide for the full retry rules, the delivery log, and how to replay events.
Error Handling
The API uses standard HTTP status codes:
200- Success201- Created204- No Content (successful deletion)400- Bad Request401- Unauthorized (invalid or missing API token)403- Forbidden (insufficient permissions)404- Not Found422- Validation Error429- Too Many Requests (rate limit exceeded)
Error response format:
{
"error": "Validation failed",
"errors": [
"First name can't be blank",
"Email is invalid"
]
}Pagination
List endpoints support pagination using page and limit parameters:
curl "https://api.suresend.ai/api/partner/people?page=2&limit=50" \
-H "Authorization: Bearer YOUR_API_TOKEN"Response includes pagination metadata:
{
"people": [...],
"meta": {
"total_count": 250,
"current_page": 2,
"total_pages": 5,
"per_page": 50
}
}Best Practices
- Always verify webhook signatures - Never process webhooks without signature verification
- Handle rate limits gracefully - Respect
Retry-Afterheaders and implement exponential backoff - Use HTTPS - All API requests must use HTTPS
- Store API tokens securely - Never expose tokens in client-side code or version control
- Use pagination - Don't fetch large datasets in a single request
- Implement idempotency - Use event IDs to detect and ignore duplicate webhook deliveries
- Monitor rate limit headers - Track your usage to avoid hitting limits
Next Steps
Now that you're familiar with the basics:
- Explore the People API to manage contacts
- Learn about Events tracking for engagement data
- Set up Webhooks for real-time integrations
- Check out Custom Fields to extend contact data
Need Help?
- API Reference: Full endpoint documentation in the sidebar
- Support: [email protected]
- Community: Join our developer community (coming soon)
Happy building! 🚀
Updated about 18 hours ago
