API Reference

The KiriMel API is organized around REST. Our API has predictable resource-oriented URLs, accepts JSON-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs.

Introduction

The KiriMel API allows you to programmatically manage your email marketing operations, including campaigns, subscribers, lists, automations, and more. You can use the API to build custom integrations, automate workflows, and extend KiriMel's functionality to meet your specific needs.

Not a developer?

Use KiriMel's built-in integrations and no-code automation tools to get started with powerful email marketing without writing code. Learn more about our features.

Client Libraries

By default, the KiriMel API documentation demonstrates using curl to interact with the API over HTTP. You can also use our official SDKs or any HTTP client library.

🐘

PHP

Official SDK for PHP applications

composer require hualiglobal/kirimel-php-sdk View on GitHub → Packagist →
🐍

Python

Official SDK for Python applications

pip install kirimel-python View on GitHub → PyPI →
🟢

Node.js

Official SDK for Node.js applications

npm install @hualiglobal/kirimel-node-sdk View on GitHub → npm →

Authentication

The KiriMel API uses API keys to authenticate requests. You can view and manage your API keys in the KiriMel Dashboard.

⚠️ Important: Your API keys carry many privileges. Be sure to keep them secure! Do not share your secret API keys in publicly accessible areas such as GitHub, client-side code, or similar locations.

Authentication Methods

All API requests must be made over HTTPS. Calls made over plain HTTP will fail. API requests without authentication will also fail.

Method 1: X-API-Key Header (Recommended)

This is the recommended method for v2 API authentication:

Request Example
curl https://kirimel.com/api/lists \
  -H "X-API-Key: sk_test_YOUR_API_KEY"

Method 2: Authorization Bearer Header

Alternatively, you can use the Authorization header with Bearer token:

Request Example
curl https://kirimel.com/api/lists \
  -H "Authorization: Bearer sk_test_YOUR_API_KEY"

Test Mode vs Live Mode

API keys have prefixes that indicate their mode:

  • sk_test_ - Test mode keys (for development and testing)
  • sk_live_ - Live mode keys (for production use)

Use test mode keys to build and test your integration without affecting your live data or incurring costs.

Sample Test API Key

A sample test API key is included in all the examples throughout this documentation, so you can test any example right away. Do not submit any personally identifiable information in requests made with this key.

To test requests using your account, replace the sample API key with your actual API key or sign in to your account.

SDK Quick Start

Get up and running quickly with our official SDKs. Each SDK provides type-safe interfaces to all KiriMel API v2 endpoints.

PHP SDK

Installation

Terminal
composer require hualiglobal/kirimel-php-sdk

Quick Start

PHP
<?php
require 'vendor/autoload.php';

use KiriMel\Client;

// Initialize the client
$client = new Client([
    'api_key' => 'sk_test_xxx'
]);

// List campaigns
$campaigns = $client->campaigns->list(['limit' => 20]);

// Create a campaign
$campaign = $client->campaigns->create([
    'name' => 'Welcome Email',
    'subject' => 'Welcome to KiriMel!',
    'list_id' => 123,
    'template_id' => 456
]);

// Get campaign statistics
$stats = $client->campaigns->stats($campaign['id']);
echo "Opens: {$stats['opens']}, Clicks: {$stats['clicks']}";
?>

Python SDK

Installation

Terminal
pip install kirimel-python

Quick Start

Python
import kirimel

# Initialize the client
client = kirimel.KiriMel(
    api_key='sk_test_xxx'
)

# List campaigns
campaigns = client.campaigns.list(limit=20)

# Create a campaign
campaign = client.campaigns.create({
    'name': 'Welcome Email',
    'subject': 'Welcome to KiriMel!',
    'list_id': 123,
    'template_id': 456
})

# Get campaign statistics
stats = client.campaigns.stats(campaign['id'])
print(f"Opens: {stats['opens']}, Clicks: {stats['clicks']}")

Node.js SDK

Installation

Terminal
npm install @hualiglobal/kirimel-node-sdk

Quick Start

JavaScript
const { Client } = require('@hualiglobal/kirimel-node-sdk');

// Initialize the client
const client = new Client({
    apiKey: 'sk_test_xxx'
});

// List campaigns
const campaigns = await client.campaigns.list({ limit: 20 });

// Create a campaign
const campaign = await client.campaigns.create({
    name: 'Welcome Email',
    subject: 'Welcome to KiriMel!',
    list_id: 123,
    template_id: 456
});

// Get campaign statistics
const stats = await client.campaigns.stats(campaign.id);
console.log(`Opens: ${stats.opens}, Clicks: ${stats.clicks}`);

SDK Features

All SDKs include the following features:

  • Full API Coverage - Access to all API v2 endpoints
  • Type-Safe - Full type hints (PHP), type annotations (Python), TypeScript definitions (Node.js)
  • Error Handling - Specific exceptions for auth, rate limiting, and validation errors
  • Retry Logic - Automatic retry with exponential backoff
  • 9 Resource Clients - Campaigns, Subscribers, Lists, Segments, Templates, Forms, Conversions, Landing Pages, Workflows

Authentication

All SDKs support two authentication methods:

  • API Key - Pass api_key parameter when initializing the client
  • Environment Variable - Set KIRIMEL_API_KEY environment variable
Authentication Examples
# Method 1: API Key (recommended)
client = new Client(['api_key' => 'sk_test_xxx'])

# Method 2: Environment variable
export KIRIMEL_API_KEY=sk_test_xxx
client = new Client()

Errors

KiriMel uses conventional HTTP response codes to indicate the success or failure of an API request.

In general:

  • Codes in the 2xx range indicate success.
  • Codes in the 4xx range indicate an error that failed given the information provided (e.g., a required parameter was omitted, a campaign failed to send, etc.).
  • Codes in the 5xx range indicate an error with KiriMel's servers (these are rare).

HTTP Status Code Summary

Status Code Description
200 OK Everything worked as expected.
201 Created The resource was successfully created.
400 Bad Request The request was unacceptable, often due to missing a required parameter.
401 Unauthorized No valid API key provided.
403 Forbidden The API key doesn't have permissions to perform the request.
404 Not Found The requested resource doesn't exist.
409 Conflict The request conflicts with another request (e.g., duplicate email address).
422 Unprocessable Entity The request was well-formed but contains semantic errors (validation failed).
429 Too Many Requests Too many requests hit the API too quickly. We recommend exponential backoff of your requests.
500, 502, 503, 504 Server Errors Something went wrong on KiriMel's end. (These are rare.)

Error Response Format

All error responses follow this format:

Error Response Example
{
    "success": false,
    "message": "Validation failed",
    "errors": {
        "email": ["The email field is required."],
        "list_id": ["The specified list does not exist."]
    }
}

Error Types

Error Type Description
authentication_error Failure to properly authenticate yourself in the request.
invalid_request_error Invalid request errors arise when your request has invalid parameters.
rate_limit_error Too many requests hit the API too quickly.
validation_error The request parameters failed validation.
api_error API errors cover any other type of problem (e.g., a temporary problem with KiriMel's servers). This is extremely uncommon.

Rate Limiting

API requests are rate limited based on your subscription plan to ensure fair usage and system stability.

Rate Limit Tiers

Plan Requests per Minute API Access
Free N/A ❌ Not available
Starter N/A ❌ Not available
Pro 60 requests/minute ✅ Available
Enterprise Unlimited ✅ Available

Rate Limit Headers

Every API response includes headers indicating your rate limit status:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 55
X-RateLimit-Reset: 1740544800

Handling Rate Limits

When you exceed your rate limit, the API returns a 429 Too Many Requests status code. We recommend implementing exponential backoff:

// Exponential backoff example
async function makeRequestWithBackoff(url, options, maxRetries = 3) {
    for (let i = 0; i < maxRetries; i++) {
        const response = await fetch(url, options);

        if (response.status !== 429) return response;

        // Exponential backoff: 2^i seconds
        const backoffTime = Math.pow(2, i) * 1000;
        await new Promise(resolve => setTimeout(resolve, backoffTime));
    }
}

Pagination

List endpoints in the KiriMel API support pagination to handle large result sets efficiently.

Paginated Response Format

{
    "success": true,
    "message": "Lists retrieved successfully",
    "data": {
        "items": [...],
        "pagination": {
            "current_page": 1,
            "per_page": 25,
            "total": 100,
            "total_pages": 4,
            "has_next_page": true,
            "has_prev_page": false
        }
    }
}

Pagination Parameters

Parameter Type Description
page integer The page number to retrieve (default: 1)
per_page integer Number of items per page (default: 25, max: 100)

Filtering & Sorting

Many list endpoints support filtering and sorting to help you find the data you need.

Common Parameters

Parameter Type Description
search string Search query to filter results
sort_by string Field to sort by (e.g., "created_at", "name")
sort_order string Sort direction: "asc" or "desc" (default: "desc")
status string Filter by status (e.g., "active", "draft", "sent")

Example

# Get sent campaigns sorted by created date
curl "https://kirimel.com/api/campaigns?status=sent&sort_by=created_at&sort_order=desc" \
  -H "X-API-Key: sk_test_YOUR_API_KEY"

Core API Resources

The following endpoints provide access to KiriMel's core email marketing functionality.

Lists

Manage your mailing lists and audiences.

POST /api/lists Create a list

Create a new mailing list with the specified settings.

curl https://kirimel.com/api/lists \
  -H "X-API-Key: sk_test_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Newsletter",
    "description": "Weekly updates and offers",
    "from_name": "My Company",
    "from_email": "noreply@example.com"
  }'
$apiKey = 'sk_test_YOUR_API_KEY';
$data = [
    'name' => 'My Newsletter',
    'description' => 'Weekly updates and offers',
    'from_name' => 'My Company',
    'from_email' => 'noreply@example.com'
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://kirimel.com/api/lists');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'X-API-Key: ' . $apiKey,
    'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($ch));
$response = curl_exec($ch);
import requests

api_key = 'sk_test_YOUR_API_KEY'
url = 'https://kirimel.com/api/lists'

data = {
    'name': 'My Newsletter',
    'description': 'Weekly updates and offers',
    'from_name': 'My Company',
    'from_email': 'noreply@example.com'
}

response = requests.post(url, json=data, headers={'X-API-Key': api_key})
print(response.json())
const axios = require('axios');

const apiKey = 'sk_test_YOUR_API_KEY';

const response = await axios.post('https://kirimel.com/api/lists', {
    name: 'My Newsletter',
    description: 'Weekly updates and offers',
    from_name: 'My Company',
    from_email: 'noreply@example.com'
}, {
    headers: {
        'X-API-Key': apiKey,
        'Content-Type': 'application/json'
    }
});

console.log(response.data);

Request Body

Parameter Type Required Description
name string The name of the list
description string Description of the list
from_name string Default sender name
from_email string Default sender email

Response

{
    "success": true,
    "message": "List created successfully",
    "data": {
        "id": 123,
        "name": "My Newsletter",
        "description": "Weekly updates and offers",
        "subscriber_count": 0,
        "created_at": "2026-03-01T10:00:00Z"
    }
}
GET /api/lists List all lists

Returns a paginated list of all mailing lists for your account.

GET /api/lists/{id} Retrieve a list

Retrieves the details of an existing list. Supply the unique list ID from either a list creation request or the list list, and KiriMel will return the corresponding list information.

POST /api/lists/{id} Update a list

Updates the specified list by setting the values of the parameters passed. Any parameters not provided will be left unchanged.

DELETE /api/lists/{id} Delete a list

Permanently deletes a mailing list and all associated data. This action cannot be undone.

GET /api/lists/{id}/subscribers List list subscribers

Returns a paginated list of all subscribers in a specific list.

GET /api/lists/{id}/stats Get list statistics

Returns subscriber counts, growth metrics, and engagement statistics for a list.

Subscribers

Manage subscribers across all your lists.

POST /api/subscribers Create a subscriber

Adds a new subscriber to a list. By default, subscribers will receive a confirmation email (double opt-in). Use skip_confirmation: true to add them as directly subscribed.

# Add subscriber with double opt-in (default)
curl https://kirimel.com/api/subscribers \
  -H "X-API-Key: sk_test_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "list_id": 123,
    "email": "user@example.com",
    "first_name": "John",
    "last_name": "Doe",
    "phone": "+1234567890"
  }'

# Add subscriber directly as subscribed (skip confirmation)
curl https://kirimel.com/api/subscribers \
  -H "X-API-Key: sk_test_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "list_id": 123,
    "email": "user@example.com",
    "skip_confirmation": true
  }'
$data = [
    'list_id' => 123,
    'email' => 'user@example.com',
    'first_name' => 'John',
    'last_name' => 'Doe',
    'skip_confirmation' => true  // Set to true to skip double opt-in
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://kirimel.com/api/subscribers');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'X-API-Key: ' . $apiKey,
    'Content-Type: application/json'
]);
$response = curl_exec($ch);
const axios = require('axios');

// Add subscriber directly as subscribed
const response = await axios.post('https://kirimel.com/api/subscribers', {
  list_id: 123,
  email: 'user@example.com',
  first_name: 'John',
  last_name: 'Doe',
  skip_confirmation: true  // Skip double opt-in, add as subscribed
}, {
  headers: {
    'X-API-Key': 'sk_test_YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
});
GET /api/subscribers List all subscribers

Returns a paginated list of subscribers across all lists with optional search and filtering.

GET /api/subscribers/{id} Retrieve a subscriber

Retrieves the details of an existing subscriber including stats and activity history.

POST /api/subscribers/{id} Update a subscriber

Updates the specified subscriber by setting the values of the parameters passed.

DELETE /api/subscribers/{id} Delete a subscriber

Permanently deletes a subscriber from all lists. This action cannot be undone.

POST /api/subscribers/{id}/unsubscribe Unsubscribe a subscriber

Unsubscribes a subscriber from all lists they are subscribed to.

POST /api/subscribers/{id}/tags Add tags to subscriber

Adds one or more tags to a subscriber for segmentation purposes.

DELETE /api/subscribers/{id}/tags/{tag} Remove tag from subscriber

Removes a specific tag from a subscriber.

GET /api/subscribers/{id}/activity Get subscriber activity

Returns a paginated list of all activity events for a specific subscriber.

💡 Bulk Import

To import multiple subscribers at once, simply make multiple POST requests to /api/subscribers or use the official PHP SDK, Python SDK, or Node.js SDK which provide convenient bulk import methods.

Campaigns

Create, manage, and send email campaigns.

POST /api/campaigns Create a campaign

Create a new email campaign with the specified settings and content.

curl https://kirimel.com/api/campaigns \
  -H "X-API-Key: sk_test_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Summer Sale",
    "subject_line": "Don'\''t Miss Out! 50% Off Everything",
    "preview_text": "Our biggest sale of the year is here",
    "content_html": "

Summer Sale!

50% off everything

", "from_name": "My Brand", "reply_to_email": "noreply@example.com", "list_id": 123 }'
$data = [
    'name' => 'Summer Sale',
    'subject_line' => "Don't Miss Out! 50% Off Everything",
    'content_html' => '

Summer Sale!

50% off everything

', 'from_name' => 'My Brand', 'reply_to_email' => 'noreply@example.com', 'list_id' => 123 ]; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://kirimel.com/api/campaigns'); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'X-API-Key: ' . $apiKey, 'Content-Type: application/json' ]); $response = curl_exec($ch);
GET /api/campaigns List all campaigns

Returns a paginated list of all campaigns.

GET /api/campaigns/{id} Retrieve a campaign

Retrieves the details of an existing campaign.

POST /api/campaigns/{id} Update a campaign

Updates the specified campaign by setting the values of the parameters passed.

DELETE /api/campaigns/{id} Delete a campaign

Permanently deletes a campaign. This action cannot be undone.

POST /api/campaigns/{id}/send Send a campaign

Immediately sends a campaign to all subscribers.

POST /api/campaigns/{id}/schedule Schedule a campaign

Schedules a campaign to be sent at a specific future date/time.

GET /api/campaigns/{id}/stats Get campaign statistics

Returns opens, clicks, bounces, and other statistics for a campaign.

Automations

Manage email automation workflows.

POST /api/automations Create an automation

Create a new automated email workflow based on triggers.

GET /api/automations List all automations

Returns a paginated list of all automations.

GET /api/automations/{id} Retrieve an automation

Retrieves the details of an existing automation.

POST /api/automations/{id} Update an automation

Updates the specified automation.

DELETE /api/automations/{id} Delete an automation

Permanently deletes an automation.

Advanced Features

Advanced API endpoints for segmentation, forms, conversions, CRM, and behavioral tracking.

Segments

Manage dynamic subscriber segments with RFM analysis and custom conditions.

POST /api/segments Create a segment

Create a new dynamic segment with RFM conditions or custom filters.

GET /api/segments List all segments

Returns all dynamic segments with their current subscriber counts.

GET /api/segments/{id} Retrieve a segment

Retrieves the details of an existing segment including conditions and subscriber count.

POST /api/segments/{id} Update a segment

Updates the specified segment's conditions or settings.

DELETE /api/segments/{id} Delete a segment

Permanently deletes a dynamic segment.

GET /api/segments/{id}/subscribers Get segment subscribers

Returns all subscribers matching the segment criteria with pagination.

Forms & Popups

Manage forms and collect submissions from your website.

POST /api/forms Create a form

Create a new form or popup with custom fields.

GET /api/forms List all forms

Returns all forms with their submission counts and conversion rates.

GET /api/forms/{id} Retrieve a form

Retrieves form configuration including fields and settings.

POST /api/forms/{id} Update a form

Updates the specified form's configuration.

DELETE /api/forms/{id} Delete a form

Permanently deletes a form.

GET /api/forms/{id}/submissions Get form submissions

Returns all submissions for a specific form with pagination.

Conversions

Track revenue and conversions from email campaigns.

POST /api/conversions Track a conversion

Record a conversion event (purchase, signup, etc.) attributed to a campaign.

GET /api/conversions List conversions

Returns all conversion events with filtering and pagination.

GET /api/conversions/{id} Retrieve a conversion

Retrieves detailed information about a specific conversion.

DELETE /api/conversions/{id} Delete a conversion

Deletes a specific conversion record.

GET /api/conversions/stats Get conversion statistics

Returns aggregated revenue statistics by campaign and time period.

Lead Scoring & CRM

Access subscriber profiles, activity timelines, and lead scoring data.

POST /api/leads/scores Update lead score

Manually update a subscriber's lead score.

GET /api/leads/scores List lead scores

Returns all subscribers with their lead scores.

GET /api/leads/{id}/score Get lead score

Returns the lead score for a specific subscriber.

POST /api/leads/tags Add tags to lead

Adds one or more tags to a subscriber for segmentation.

DELETE /api/leads/tags Remove tags from lead

Removes one or more tags from a subscriber.

GET /api/leads/{id}/notes Get lead notes

Returns all notes for a specific subscriber.

POST /api/leads/{id}/notes Add lead note

Adds a private note to a subscriber's profile.

GET /api/leads Search leads

Search and filter leads with pagination.

POST /api/leads/{id}/convert Convert lead

Convert a lead to a customer with associated data.

GET /api/leads/activities Get lead activities

Returns activity timeline for leads.

Behavioral Tracking

Track visitor behavior on your website for targeted email automation.

POST /api/track/event Track custom event

Record a custom tracking event for website visitor behavior.

POST /api/track/pageview Track page view

Record a page view event for website visitor tracking.

POST /api/track/click Track link click

Track when a visitor clicks a link on your website.

GET /api/track/events List events

Returns tracking events with filtering and pagination.

GET /api/track/profile/{id} Get tracking profile

Returns the complete tracking profile for a visitor.

Transactional Email

Send individual transactional emails and manage SES settings.

POST /api/email/send Send transactional email

Send a single transactional email to a recipient.

curl https://kirimel.com/api/email/send \
  -H "X-API-Key: sk_test_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "recipient@example.com",
    "subject": "Welcome to Our Service!",
    "html": "

Welcome!

Thank you for signing up.

", "text": "Welcome! Thank you for signing up.", "from_name": "My App", "reply_to": "support@example.com" }'
$data = [
    'to' => 'recipient@example.com',
    'subject' => 'Welcome to Our Service!',
    'html' => '

Welcome!

Thank you for signing up.

', 'text' => 'Welcome! Thank you for signing up.', 'from_name' => 'My App', 'reply_to' => 'support@example.com' ]; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://kirimel.com/api/email/send'); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'X-API-Key: ' . $apiKey, 'Content-Type: application/json' ]); $response = curl_exec($ch);
GET /api/email/quota Get SES quota

Returns your current SES send quota and usage statistics.

GET /api/email/verified Get verified emails

Returns a list of verified email addresses in your SES account.

POST /api/email/verify Verify email address

Requests verification for a new email address in SES.

Webhooks

Configure webhooks to receive real-time notifications about events in your KiriMel account.

Setting Up Webhooks

Webhooks allow you to receive HTTP POST requests when events occur in your KiriMel account. Configure webhooks in the Settings page.

Supported Events

campaign.sent Triggered when a campaign is sent
campaign.opened When a subscriber opens an email
campaign.clicked When a subscriber clicks a link
subscriber.bounced When an email bounces
subscriber.unsubscribed When a subscriber opts out
subscriber.complained When a subscriber marks as spam
form.submitted When a form is submitted
conversion.tracked When a conversion is recorded

Webhook Payload Format

All webhook payloads follow this structure:

{
    "event": "campaign.opened",
    "data": {
        "campaign_id": 123,
        "subscriber_id": 456,
        "email": "user@example.com",
        "opened_at": "2026-03-01T10:30:00Z",
        "ip_address": "192.168.1.1",
        "user_agent": "Mozilla/5.0..."
    },
    "timestamp": "2026-03-01T10:30:00Z"
}

Signature Verification

Webhook payloads include a signature header for verification:

X-KiriMel-Signature: sha256=abc123def456...

Verify the signature using your webhook secret:

$signature = $_SERVER['HTTP_KIRIMEL_SIGNATURE'];
$payload = file_get_contents('php://input');
$expectedSignature = hash_hmac('sha256', $payload, $webhookSecret);

if (hash_equals($expectedSignature, $signature)) {
    // Signature is valid, process webhook
} else {
    // Invalid signature, reject request
}

Retry Policy

If your webhook endpoint returns a non-2xx status code or times out, KiriMel will retry delivery with exponential backoff:

  • Retry 1: 1 minute after failure
  • Retry 2: 5 minutes after failure
  • Retry 3: 30 minutes after failure
  • Retry 4: 2 hours after failure

After 4 failed attempts, the webhook is marked as failed and won't be retried.

Ready to Integrate?

Get your API key and start building powerful email marketing integrations today.

Get Your API Key