SimRelay API (1.0)

Download OpenAPI specification:

API documentation for SimRelay.

Authentication

SimRelay supports multiple authentication methods:

1. OAuth2 (SimRelay Chrome Extension)

The SimRelay Chrome Extension uses OAuth2 Authorization Code flow with PKCE for secure authentication. Simply install the extension and sign in with your SimRelay account.

Token Expiration:

  • Access tokens: 15 days
  • Refresh tokens: 30 days

2. API Keys

For server-to-server integrations, use API keys. Create them at Settings > API Keys.

Authorization: Bearer sk_live_xxxxxxxxxxxxx

3. Personal Access Tokens

For mobile apps or simple integrations, use the /api/auth/login endpoint to obtain a token.

Health

Basic health check

Returns 200 OK if the application and database are accessible. Lightweight check for load balancers and monitoring.

Responses

Response samples

Content type
application/json
{
  • "status": "ok",
  • "timestamp": "2019-08-24T14:15:22Z"
}

Detailed health check

Checks database, cache, and queue system. Returns detailed status for each service.

Responses

Response samples

Content type
application/json
{
  • "status": "ok",
  • "timestamp": "2019-08-24T14:15:22Z",
  • "checks": {
    }
}

SIM Lock

Acquire a lock on a SIM

Authorizations:
bearerAuthapiKeyAuth
path Parameters
hosted_sim
required
integer

Responses

Get lock status for a SIM

Authorizations:
bearerAuthapiKeyAuth
path Parameters
hosted_sim
required
integer

Responses

Release a lock on a SIM

Authorizations:
bearerAuthapiKeyAuth
path Parameters
hosted_sim
required
integer

Responses

Messages

Get messages for a SIM

Authorizations:
bearerAuthapiKeyAuth
path Parameters
hosted_sim
required
integer
query Parameters
per_page
integer [ 1 .. 100 ]

Number of messages per page (default 50)

limit
integer [ 1 .. 100 ]

Alternative to per_page for compatibility (default 50)

page
integer >= 1

Page number for pagination (default 1)

Responses

Send a message via SIM

Authorizations:
bearerAuthapiKeyAuth
path Parameters
hosted_sim
required
integer
Request Body schema: application/json
required
to
required
string

Recipient phone number

text
required
string

Message content

Responses

Request samples

Content type
application/json
{
  • "to": "+1234567890",
  • "text": "Hello, this is a test message"
}

User

Get current authenticated user

Returns user information and authentication context (Sanctum token or API key)

Authorizations:
bearerAuthapiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "user": {
    },
  • "auth_type": "api_key",
  • "organization": {
    },
  • "api_key": {
    }
}

Auth

Login with email and password (mobile)

Request Body schema: application/json
required
email
required
string <email>
password
required
string <password>

Responses

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{
  • "2fa_required": true,
  • "tmp_token": "string"
}

Complete 2FA login with TOTP code

Request Body schema: application/json
required
tmp_token
required
string
code
required
string

TOTP code from authenticator app

Responses

Request samples

Content type
application/json
{
  • "tmp_token": "string",
  • "code": "string"
}

Response samples

Content type
application/json
{
  • "token": "string",
  • "user": {
    }
}

SIMs

Get all accessible SIMs for the user

Retrieve all SIMs that the authenticated user has access to through their team and organization memberships, or for API keys, all SIMs in the organization.

Authorizations:
bearerAuthapiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": [
    ]
}

API Keys

List all API keys for the authenticated user

Returns all API keys belonging to the authenticated user's organization. Only accessible via Sanctum authentication, not API keys.

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "data": [
    ]
}

Create a new API key

Creates a new API key for the authenticated user's organization. Only accessible via Sanctum authentication.

Authorizations:
bearerAuth
Request Body schema: application/json
required
name
required
string

Display name for the API key

permissions
required
Array of strings
Items Enum: "numbers.read" "numbers.lock" "messages.read" "webhooks.receive"

Array of permission strings

Responses

Request samples

Content type
application/json
{
  • "name": "Production API Key",
  • "permissions": [
    ]
}

Response samples

Content type
application/json
{
  • "api_key": {
    },
  • "plain_text_key": "sk_live_1234567890abcdef"
}

Get a specific API key

Returns details of a specific API key. Only accessible via Sanctum authentication.

Authorizations:
bearerAuth
path Parameters
api_key
required
integer

API key ID

Responses

Response samples

Content type
application/json
{
  • "id": 1,
  • "name": "Production API Key",
  • "key_prefix": "sk_live_1234",
  • "permissions": [
    ],
  • "last_used_at": "2024-01-15T10:30:00Z",
  • "created_at": "2024-01-01T00:00:00Z",
  • "updated_at": "2024-01-01T00:00:00Z"
}

Update an API key

Updates an existing API key's name or permissions. Only accessible via Sanctum authentication.

Authorizations:
bearerAuth
path Parameters
api_key
required
integer

API key ID

Request Body schema: application/json
required
name
string

Display name for the API key

permissions
Array of strings
Items Enum: "numbers.read" "numbers.lock" "messages.read" "webhooks.receive"

Array of permission strings

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "permissions": [
    ]
}

Response samples

Content type
application/json
{
  • "id": 1,
  • "name": "Production API Key",
  • "key_prefix": "sk_live_1234",
  • "permissions": [
    ],
  • "last_used_at": "2024-01-15T10:30:00Z",
  • "created_at": "2024-01-01T00:00:00Z",
  • "updated_at": "2024-01-01T00:00:00Z"
}

Delete an API key

Deletes an API key. This action cannot be undone. Only accessible via Sanctum authentication.

Authorizations:
bearerAuth
path Parameters
api_key
required
integer

API key ID

Responses

Regenerate an API key

Regenerates the secret key for an existing API key. The old key will immediately stop working. Only accessible via Sanctum authentication.

Authorizations:
bearerAuth
path Parameters
api_key
required
integer

API key ID

Responses

Response samples

Content type
application/json
{
  • "api_key": {
    },
  • "plain_text_key": "sk_live_9876543210fedcba"
}

Webhook Integrations

List all webhook integrations

Returns all webhook integrations for the authenticated user's organization.

Authorizations:
bearerAuthapiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "organization": {
    }
}

Create a new webhook integration

Creates a new webhook integration. A secure secret is auto-generated and returned (only shown once).

Authorizations:
bearerAuthapiKeyAuth
Request Body schema: application/json
required
name
required
string <= 255 characters

Display name for the webhook

url
required
string <uri> <= 2048 characters

URL to send webhook payloads to

object

Custom headers to include in webhook requests

timeout_seconds
integer [ 1 .. 120 ]

Request timeout in seconds (default 30)

retry_count
integer [ 0 .. 10 ]

Number of retry attempts on failure (default 3)

Responses

Request samples

Content type
application/json
{
  • "name": "My Webhook",
  • "headers": {
    },
  • "timeout_seconds": 30,
  • "retry_count": 3
}

Response samples

Content type
application/json
{
  • "message": "Webhook integration created successfully.",
  • "data": {
    }
}

Get a specific webhook integration

Returns details of a specific webhook integration including its mappings.

Authorizations:
bearerAuthapiKeyAuth
path Parameters
webhook_integration
required
integer

Webhook integration ID

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a webhook integration

Updates an existing webhook integration.

Authorizations:
bearerAuthapiKeyAuth
path Parameters
webhook_integration
required
integer

Webhook integration ID

Request Body schema: application/json
required
name
required
string <= 255 characters
url
required
string <uri> <= 2048 characters
object
timeout_seconds
integer [ 1 .. 120 ]
retry_count
integer [ 0 .. 10 ]
is_active
boolean

Enable or disable the webhook

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "headers": {
    },
  • "timeout_seconds": 1,
  • "retry_count": 10,
  • "is_active": true
}

Response samples

Content type
application/json
{
  • "message": "Webhook integration updated successfully.",
  • "data": {
    }
}

Delete a webhook integration

Deletes a webhook integration and all its mappings.

Authorizations:
bearerAuthapiKeyAuth
path Parameters
webhook_integration
required
integer

Webhook integration ID

Responses

Response samples

Content type
application/json
{
  • "message": "Webhook integration deleted successfully."
}

Regenerate webhook secret

Regenerates the webhook secret. The old secret will immediately stop working.

Authorizations:
bearerAuthapiKeyAuth
path Parameters
webhook_integration
required
integer

Webhook integration ID

Responses

Response samples

Content type
application/json
{
  • "message": "Webhook secret regenerated successfully.",
  • "data": {
    }
}

Test a webhook integration

Sends a test payload to the webhook URL to verify connectivity.

Authorizations:
bearerAuthapiKeyAuth
path Parameters
webhook_integration
required
integer

Webhook integration ID

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "http_status": 200,
  • "response_body": "string",
  • "response_time_ms": 150
}

Webhook Mappings

List webhook mappings

Returns all mappings for a specific webhook integration.

Authorizations:
bearerAuthapiKeyAuth
path Parameters
webhook_integration
required
integer

Webhook integration ID

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "webhook_integration": {
    }
}

Create a webhook mapping

Creates a new mapping to associate a team with a webhook integration.

Authorizations:
bearerAuthapiKeyAuth
path Parameters
webhook_integration
required
integer

Webhook integration ID

Request Body schema: application/json
required
team_id
required
integer

Team ID to associate with this webhook

forwarding_mode
required
string
Enum: "always" "lock_required"

When to forward messages:

  • always: Forward all messages for this team
  • lock_required: Only forward messages when team has an active lock

Responses

Request samples

Content type
application/json
{
  • "team_id": 1,
  • "forwarding_mode": "always"
}

Response samples

Content type
application/json
{
  • "message": "Webhook mapping created successfully.",
  • "data": {
    }
}

Get a specific webhook mapping

Returns details of a specific webhook mapping.

Authorizations:
bearerAuthapiKeyAuth
path Parameters
webhook_integration
required
integer

Webhook integration ID

webhook_mapping
required
integer

Webhook mapping ID

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a webhook mapping

Updates an existing webhook mapping.

Authorizations:
bearerAuthapiKeyAuth
path Parameters
webhook_integration
required
integer

Webhook integration ID

webhook_mapping
required
integer

Webhook mapping ID

Request Body schema: application/json
required
forwarding_mode
required
string
Enum: "always" "lock_required"
is_active
boolean

Enable or disable the mapping

Responses

Request samples

Content type
application/json
{
  • "forwarding_mode": "always",
  • "is_active": true
}

Response samples

Content type
application/json
{
  • "message": "Webhook mapping updated successfully.",
  • "data": {
    }
}

Delete a webhook mapping

Deletes a webhook mapping.

Authorizations:
bearerAuthapiKeyAuth
path Parameters
webhook_integration
required
integer

Webhook integration ID

webhook_mapping
required
integer

Webhook mapping ID

Responses

Response samples

Content type
application/json
{
  • "message": "Webhook mapping deleted successfully."
}

WebSocket

Get WebSocket configuration for clients

Returns the WebSocket server URL, port, authentication method, and other necessary details for clients to connect to the configured broadcaster (e.g., Reverb).

Authorizations:
bearerAuthapiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "broadcaster": "reverb",
  • "key": "your_reverb_app_key",
  • "ws_url": "ws://localhost:8080",
  • "ws_host": "localhost",
  • "ws_port": 8080,
  • "ws_scheme": "http",
  • "force_tls": false,
  • "auth_method": "bearer_token",
  • "auth_header": "Authorization: Bearer <token>",
}

BYOS Devices

List BYOS devices

Returns a paginated list of BYOS devices for the authenticated user's organizations. Supports filtering by device status.

Authorizations:
oauth2_byos
query Parameters
status
string
Enum: "active" "disabled" "revoked" "pending_verification"

Filter devices by status

per_page
integer [ 1 .. 100 ]
Default: 15

Number of devices per page

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "meta": {
    },
  • "links": {
    }
}

Register a new BYOS device

Registers a new device with SIM slot declarations. Each SIM slot receives a verification code that must be sent via SMS to the Twilio verification number to prove SIM ownership.

Flow:

  1. App sends sim_slots array (e.g. [1] or [1, 2] for dual-SIM)
  2. Server creates device in pending_verification status with pending SIM cards
  3. Response includes a verification_code per SIM and the twilio_number to SMS it to
  4. App sends SMS containing the code to twilio_number
  5. Twilio webhook receives SMS, extracts code, activates SIM with the sender's real phone number
  6. Device transitions to active on first SIM verification
Authorizations:
oauth2_byos
Request Body schema: application/json
required
android_id
required
string^[0-9a-fA-F]{16}$

64-bit hex string from Android's Settings.Secure.ANDROID_ID. Unique per app signing key + device user combination.

sim_slots
required
Array of integers [ 1 .. 2 ] items [ items [ 1 .. 10 ] ]

SIM slot numbers to register. Each slot will receive a verification code.

device_model
required
string <= 100 characters

Android device model

app_version
required
string <= 50 characters

SimRelay app version

device_name
string <= 255 characters

User-friendly device name (optional)

Responses

Request samples

Content type
application/json
{
  • "android_id": "a1b2c3d4e5f67890",
  • "sim_slots": [
    ],
  • "device_model": "SM-S921B",
  • "app_version": "1.2.3",
  • "device_name": "Work Phone"
}

Response samples

Content type
application/json
{
  • "id": 1,
  • "android_id": "a1b2c3d4e5f67890",
  • "device_name": "Work Phone",
  • "device_model": "SM-S921B",
  • "app_version": "1.2.3",
  • "status": "pending_verification",
  • "twilio_number": "+12025551234",
  • "sim_cards": [
    ],
  • "created_at": "2019-08-24T14:15:22Z"
}

Get device details

Returns full details for a specific BYOS device including organization info and message count.

Authorizations:
oauth2_byos
path Parameters
device
required
integer

BYOS device ID

Responses

Response samples

Content type
application/json
{
  • "id": 1,
  • "android_id": "a1b2c3d4e5f67890",
  • "phone_number": "+14155551234",
  • "device_name": "Samsung Galaxy S24",
  • "status": "active",
  • "is_online": true,
  • "created_at": "2019-08-24T14:15:22Z",
  • "twilio_number": "+12025551234",
  • "sim_cards": [
    ],
  • "device_model": "SM-S921B",
  • "app_version": "1.2.3",
  • "config_version": 1,
  • "battery_level": 85,
  • "last_seen_at": "2019-08-24T14:15:22Z",
  • "messages_received_count": 42,
  • "organization": {
    },
  • "updated_at": "2019-08-24T14:15:22Z"
}

Update device metadata

Updates device name, phone number, or app version. Phone number changes are synced to the HostedSim record.

Authorizations:
oauth2_byos
path Parameters
device
required
integer

BYOS device ID

Request Body schema: application/json
required
device_name
string <= 255 characters
phone_number
string

Phone number in E.164 format

app_version
string <= 50 characters

Responses

Request samples

Content type
application/json
{
  • "device_name": "Updated Device Name",
  • "phone_number": "+14155559999",
  • "app_version": "1.3.0"
}

Response samples

Content type
application/json
{
  • "id": 1,
  • "android_id": "a1b2c3d4e5f67890",
  • "phone_number": "+14155551234",
  • "device_name": "Samsung Galaxy S24",
  • "status": "active",
  • "is_online": true,
  • "created_at": "2019-08-24T14:15:22Z",
  • "twilio_number": "+12025551234",
  • "sim_cards": [
    ],
  • "device_model": "SM-S921B",
  • "app_version": "1.2.3",
  • "config_version": 1,
  • "battery_level": 85,
  • "last_seen_at": "2019-08-24T14:15:22Z",
  • "messages_received_count": 42,
  • "organization": {
    },
  • "updated_at": "2019-08-24T14:15:22Z"
}

Delete device

Permanently deletes a device and all associated records including SIM cards and hosted SIMs. Message logs are preserved (hosted_sim_id set to null). This action cannot be undone.

Authorizations:
oauth2_byos
path Parameters
device
required
integer

BYOS device ID

Responses

Disable device

Temporarily disables a device. Device status becomes 'disabled' and will not receive messages.

Authorizations:
oauth2_byos
path Parameters
device
required
integer

BYOS device ID

Responses

Response samples

Content type
application/json
{
  • "id": 1,
  • "android_id": "a1b2c3d4e5f67890",
  • "phone_number": "+14155551234",
  • "device_name": "Samsung Galaxy S24",
  • "status": "active",
  • "is_online": true,
  • "created_at": "2019-08-24T14:15:22Z",
  • "twilio_number": "+12025551234",
  • "sim_cards": [
    ],
  • "device_model": "SM-S921B",
  • "app_version": "1.2.3",
  • "config_version": 1,
  • "battery_level": 85,
  • "last_seen_at": "2019-08-24T14:15:22Z",
  • "messages_received_count": 42,
  • "organization": {
    },
  • "updated_at": "2019-08-24T14:15:22Z"
}

Enable device

Re-enables a disabled device. Device status becomes 'active' and will resume receiving messages.

Authorizations:
oauth2_byos
path Parameters
device
required
integer

BYOS device ID

Responses

Response samples

Content type
application/json
{
  • "id": 1,
  • "android_id": "a1b2c3d4e5f67890",
  • "phone_number": "+14155551234",
  • "device_name": "Samsung Galaxy S24",
  • "status": "active",
  • "is_online": true,
  • "created_at": "2019-08-24T14:15:22Z",
  • "twilio_number": "+12025551234",
  • "sim_cards": [
    ],
  • "device_model": "SM-S921B",
  • "app_version": "1.2.3",
  • "config_version": 1,
  • "battery_level": 85,
  • "last_seen_at": "2019-08-24T14:15:22Z",
  • "messages_received_count": 42,
  • "organization": {
    },
  • "updated_at": "2019-08-24T14:15:22Z"
}

Get device configuration

Returns server configuration for the device including intervals, limits, features, and current plan details.

Authorizations:
oauth2_byos
path Parameters
device
required
integer

BYOS device ID

Responses

Response samples

Content type
application/json
{
  • "device": {
    },
  • "intervals": {
    },
  • "limits": {
    },
  • "features": {
    },
  • "metadata": {
    }
}

Send device heartbeat

Updates device health metrics and last_seen timestamp. Marks device as online and broadcasts status change event if device was offline.

The server uses adaptive timeouts based on Doze Mode state:

  • Normal: device marked offline after 360 seconds (6 minutes)
  • Doze Mode: device marked offline after 960 seconds (16 minutes)

Email alerts are deferred until two consecutive intervals are missed.

Authorizations:
oauth2_byos
path Parameters
device
required
integer

BYOS device ID

Request Body schema: application/json
optional
battery_level
integer [ 0 .. 100 ]

Current battery percentage (optional)

signal_strength
integer [ 0 .. 100 ]

Current signal strength percentage (optional, backward compat - updates first SIM card)

is_in_doze_mode
boolean
Default: false

Whether the Android device is currently in Doze Mode. Server uses a longer timeout (960s vs 360s) for doze devices.

Array of objects

Per-SIM signal strength updates (optional)

Responses

Request samples

Content type
application/json
{
  • "battery_level": 85,
  • "signal_strength": 75,
  • "is_in_doze_mode": false,
  • "sim_cards": [
    ]
}

Response samples

Content type
application/json
{
  • "success": true,
  • "next_heartbeat_in": 300,
  • "server_time": "2019-08-24T14:15:22Z"
}

Submit received SMS message

Submits an SMS message received by the BYOS device. Message is validated and queued for async processing.

Authorizations:
oauth2_byos
path Parameters
device
required
integer

BYOS device ID

Request Body schema: application/json
required
from
required
string <= 20 characters

Sender phone number

body
required
string <= 1600 characters

SMS message content

message_id
required
string <uuid>

Unique message identifier from device

received_at
string <date-time>

Timestamp when device received message (optional)

sim_slot
integer [ 1 .. 2 ]

SIM slot number for dual-SIM devices (optional)

Responses

Request samples

Content type
application/json
{
  • "from": "+19876543210",
  • "body": "Your verification code is 123456",
  • "message_id": "550e8400-e29b-41d4-a716-446655440000",
  • "received_at": "2019-08-24T14:15:22Z",
  • "sim_slot": 1
}

Response samples

Content type
application/json
{
  • "message": "SMS received and queued for processing",
  • "message_id": "550e8400-e29b-41d4-a716-446655440000"
}

Add SIM card to device

Adds a new SIM card slot to an existing device, pending SMS verification. Returns a verification code that must be sent via SMS to the Twilio number.

Authorizations:
oauth2_byos
path Parameters
device
required
integer

BYOS device ID

Request Body schema: application/json
required
sim_slot
required
integer [ 1 .. 10 ]

Physical SIM slot number on the device

Responses

Request samples

Content type
application/json
{
  • "sim_slot": 2
}

Response samples

Content type
application/json
{
  • "id": 1,
  • "sim_slot": 1,
  • "phone_number": null,
  • "status": "pending",
  • "verification_code": "SR-A2B3",
  • "twilio_number": "+12025551234"
}

Update SIM card

Updates SIM card metadata like phone number or slot number. Phone number changes sync to the associated HostedSim.

Authorizations:
oauth2_byos
path Parameters
device
required
integer

BYOS device ID

simCard
required
integer

SIM card ID

Request Body schema: application/json
required
phone_number
string

Phone number in E.164 format

sim_slot
integer or null [ 1 .. 10 ]

Responses

Request samples

Content type
application/json
{
  • "phone_number": "+14155559999",
  • "sim_slot": 2
}

Response samples

Content type
application/json
{
  • "id": 1,
  • "phone_number": "+14155551234",
  • "sim_slot": 1,
  • "status": "active",
  • "signal_strength": 75,
  • "is_active": true,
  • "hosted_sim_id": 10,
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Remove SIM card

Deactivates a SIM card from the device. Sets status to inactive.

Authorizations:
oauth2_byos
path Parameters
device
required
integer

BYOS device ID

simCard
required
integer

SIM card ID

Responses

Re-trigger SIM verification

Generates a new verification code for a pending or inactive SIM card. Use this when the original code has expired (codes expire after 5 minutes). Cannot be used on already-active SIM cards.

Authorizations:
oauth2_byos
path Parameters
device
required
integer

BYOS device ID

simCard
required
integer

SIM card ID

Responses

Response samples

Content type
application/json
{
  • "id": 1,
  • "sim_slot": 1,
  • "phone_number": null,
  • "status": "pending",
  • "verification_code": "SR-A2B3",
  • "twilio_number": "+12025551234"
}

Webhooks

Twilio SMS verification webhook

Receives incoming SMS from Twilio when a BYOS device sends its verification code. This endpoint is called by Twilio, not by the app directly.

Flow:

  1. Device SIM sends SMS containing verification code (e.g. SR-A2B3) to the Twilio number
  2. Twilio forwards the SMS to this webhook as a form-encoded POST
  3. Server extracts the verification code from the SMS body
  4. Server activates the SIM card with the sender's real phone number from the From field

Security: Requests are validated using Twilio request signature (X-Twilio-Signature header).

Request Body schema: application/x-www-form-urlencoded
required
From
string

Sender phone number in E.164 format (the SIM's real number)

To
string

Twilio phone number that received the SMS

Body
string

SMS body containing the verification code

MessageSid
string

Twilio message SID

AccountSid
string

Twilio account SID

Responses