KimePush Docs

1

Create a project

Projects isolate API keys, credentials, contacts, templates, logs, and webhooks.

2

Configure sending

Upload FCM/APNs/Web Push credentials for push. Add and verify email domains, or use the shared KimePush domain for testing.

3

Register contacts and tokens

Send contact names and topics from your app or backend. KimePush stores topics for later broadcasts.

4

Send and observe

Use transactional APIs or broadcasts. Delivery events flow into logs and optional webhooks.

Authentication

API requests use Authorization: Bearer <key>.

pk_live_...
Secret key
Server-side only. Sends push, broadcasts, and manages contacts.
pk_pub_...
Publishable key
Client-side. Use for token registration only.
pk_test_...
Test key
Development and CI. Simulates delivery without calling providers.

Project Setup

Push

Android uses FCM service account JSON. iOS uses APNs team id, key id, bundle id, environment, and .p8 key. Web Push uses VAPID keys generated by KimePush.

Contacts and Topics

Contacts are project-scoped profiles with email, external id, name fields, topics, and subscription status. A topic is an audience or subscription such as weekly_digest, product_updates, or launch. Broadcasts match contacts that have every selected topic.

{
  "email": "asha@example.com",
  "external_id": "user_123",
  "first_name": "Asha",
  "last_name": "Kumar",
  "topics": ["weekly_digest", "launch"]
}

// Broadcast matching uses AND semantics:
// contact must have weekly_digest AND launch.

API Reference

POST/v1/tokens/registerPublishable or secret key

Register a mobile or web push token. Optional contact fields attach the token to a contact for topic broadcasts.

Request body
{
  "user_id": "user_123",
  "platform": "fcm",
  "token": "device_token...",
  "environment": "production",
  "email": "asha@example.com",
  "first_name": "Asha",
  "topics": ["product_updates"],
  "metadata": {
    "app_version": "2.1.0"
  }
}
POST/v1/contactsSecret key

Create or update a project contact with names and topics.

Request body
{
  "email": "asha@example.com",
  "external_id": "user_123",
  "first_name": "Asha",
  "last_name": "Kumar",
  "topics": ["weekly_digest", "product_updates"]
}
POST/v1/contacts/:id/topicsSecret key

Replace the topics assigned to a contact from your backend.

Request body
{
  "topics": ["launch", "weekly_digest"]
}
POST/v1/notifySecret or test key

Send one push notification to all active devices for one user.

Request body
{
  "to": "user_123",
  "title": "Your order shipped",
  "body": "Arrives Thursday",
  "deep_link": "myapp://orders/ORD-9981",
  "data": { "order_id": "ORD-9981" },
  "priority": "high",
  "idempotency_key": "order-shipped-ORD-9981"
}
POST/v1/broadcastSecret or test key

Broadcast mobile push or web push to tokens matching selected topics. Multiple topics use AND semantics.

Request body
{
  "channel": "mobile_push",
  "title": "New update available",
  "body": "Version 2.1 is ready to install",
  "topics": ["product_updates"]
}
GET/v1/notifications/:idSecret key

Read push notification delivery status and per-token delivery details.

Webhooks

Add HTTPS endpoints in Project Settings. KimePush signs each payload with the webhook secret shown once at creation time.

Push events
push.deliveredpush.failedpush.token_deactivatedweb_push.deliveredweb_push.failedweb_push.token_deactivated
Contact events
contact.createdcontact.updatedcontact.unsubscribed
Signature verification
const signature = req.headers['x-kimepush-signature'];
const timestamp = req.headers['x-kimepush-timestamp'];
const expected = 'sha256=' +
  crypto.createHmac('sha256', webhookSecret)
        .update(timestamp + '.' + rawBody)
        .digest('hex');

if (!crypto.timingSafeEqual(
  Buffer.from(signature), Buffer.from(expected)
)) throw new Error('Invalid signature');

Status API

GET /status is backed by the KimePush status incident tables, not hardcoded page text. Admin can create and update incidents from the admin console. The endpoint returns overall state and active incidents for the public status page.

curl https://api.kimepush.kimevik.com/status

{
  "status": "operational",
  "incidents": []
}

Error Codes

Every error response has the shape { "error": "<code>", "message": "<detail>" }. error is the stable code to branch on; message is a human-readable detail that can vary per request.

auth
unauthorized401The request is missing a valid API key or session credential.
forbidden403The credential used cannot perform this action (e.g. a publishable key on a secret-key-only route).
billing
no_customer400No Stripe customer exists yet for this account.
no_stripe_price400No Stripe price is configured for the requested plan.
stripe_publishable_key_missing400Stripe is not fully configured for this environment.
account_suspended403This account is suspended and cannot send notifications or emails.
product_not_enabled403The product (e.g. email_push) is not enabled for this account.
stripe_error502Stripe returned an error while processing this request.
dashboard
delete_confirmation_required400Destructive action requires an explicit confirmation field.
email
invalid_ses_event400The inbound SES event payload could not be parsed.
invalid_sns_payload400The inbound SNS payload could not be parsed.
invalid_subscribe_url400The SNS SubscribeURL host is not an expected AWS SNS endpoint.
no_contacts400No contacts matched the requested topics/tags for this broadcast.
too_many_contacts400The matched contact count exceeds the broadcast limit (5000).
unsupported_sns_signature_version400The SNS message used a signature version KimePush does not verify.
invalid_sns_signature401The SNS message signature failed verification.
sns_topic_mismatch403The SNS message's topic ARN does not match the configured SES topic.
domain_taken409This sending domain is already claimed by another project.
domain_limit_reached429This account has reached its sending-domain limit.
ses_error502AWS SES returned an error while sending this email.
sns_subscription_failed502KimePush could not confirm the SNS subscription.
general
bad_request400The request body failed validation. See the message field for which field.
not_found404The requested resource does not exist, or does not belong to this project.
payload_too_large413The request body exceeds the size limit for this endpoint.
rate_limited429Too many requests from this API key in the current window.
internal_error500An unexpected server error. Retry with backoff; contact support if it persists.
push
invalid_apns_token400The token does not look like a 64-character hex APNs device token.
no_tokens400No active device tokens matched the requested platform/topics/tags.
not_configured400The requested platform (fcm/apns/web) has no credentials configured for this project, or the token's environment doesn't match.
too_many_tokens400The matched token count exceeds the broadcast limit.
quota_exceeded429This account has reached its monthly notification/email quota.
team
email_mismatch403The invite token does not match the signed-in account's email.
already_invited409This email already has a pending or accepted team invite.

DLQ and Error Management

End users generally do not need to know about the internal SNS dead-letter queue. It is an operator control for KimePush reliability.

A DLQ stores event messages that SNS could not deliver to KimePush after retries. KimePush should monitor this in Admin because DLQ messages mean delivery telemetry may be delayed or missing.

User-facing error handling is shown through logs, webhook delivery status, permanent token failures, bounces, complaints, and status incidents.