iMessage API

Send iMessage programmatically from your app or AI agent. Managed infrastructure, no Mac to run — one API for iMessage, WhatsApp, LinkedIn and email.

< 4
s

Avg Response

+ 50

Endpoints

99.9
%

Uptime

1import requests
2
3response = requests.post(
4    "https://api.linkupapi.com/v2/messages",
5    headers={"x-api-key": "YOUR_API_KEY"},
6    json={
7        "account_id": "YOUR_IMESSAGE_ACCOUNT_ID",
8        "action": "send",
9        "params": {
10            "phone_number": "+13231112233",
11            "message_text": "Hi Jane, saw your team is hiring SDRs. Open to a quick chat this week?"
12        }
13    }
14)
15
16print(response.json())
1const response = await fetch("https://api.linkupapi.com/v2/messages", {
2  method: "POST",
3  headers: {
4    "x-api-key": "YOUR_API_KEY",
5    "Content-Type": "application/json"
6  },
7  body: JSON.stringify({
8    account_id: "YOUR_IMESSAGE_ACCOUNT_ID",
9    action: "send",
10    params: {
11      phone_number: "+13231112233",
12      message_text: "Hi Jane, saw your team is hiring SDRs. Open to a quick chat this week?"
13    }
14  })
15});
16
17const data = await response.json();
18console.log(data);
1<?php
2$payload = [
3    "account_id" => "YOUR_IMESSAGE_ACCOUNT_ID",
4    "action" => "send",
5    "params" => [
6        "phone_number" => "+13231112233",
7        "message_text" => "Hi Jane, saw your team is hiring SDRs. Open to a quick chat this week?"
8    ]
9];
10
11$ch = curl_init("https://api.linkupapi.com/v2/messages");
12curl_setopt($ch, CURLOPT_POST, true);
13curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
14curl_setopt($ch, CURLOPT_HTTPHEADER, [
15    "x-api-key: YOUR_API_KEY",
16    "Content-Type: application/json"
17]);
18curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
19
20$response = curl_exec($ch);
21curl_close($ch);
22echo $response;
1package main
2
3import (
4    "bytes"
5    "fmt"
6    "io"
7    "net/http"
8)
9
10func main() {
11    payload := []byte(`{
12  "account_id": "YOUR_IMESSAGE_ACCOUNT_ID",
13  "action": "send",
14  "params": {
15    "phone_number": "+13231112233",
16    "message_text": "Hi Jane, saw your team is hiring SDRs. Open to a quick chat this week?"
17  }
18}`)
19
20    req, _ := http.NewRequest("POST", "https://api.linkupapi.com/v2/messages", bytes.NewBuffer(payload))
21    req.Header.Set("x-api-key", "YOUR_API_KEY")
22    req.Header.Set("Content-Type", "application/json")
23
24    res, err := http.DefaultClient.Do(req)
25    if err != nil {
26        panic(err)
27    }
28    defer res.Body.Close()
29    body, _ := io.ReadAll(res.Body)
30    fmt.Println(string(body))
31}
1import java.net.URI;
2import java.net.http.HttpClient;
3import java.net.http.HttpRequest;
4import java.net.http.HttpResponse;
5
6public class Main {
7    public static void main(String[] args) throws Exception {
8        String payload = "{\"account_id\": \"YOUR_IMESSAGE_ACCOUNT_ID\", \"action\": \"send\", \"params\": {\"phone_number\": \"+13231112233\", \"message_text\": \"Hi Jane, open to a quick chat this week?\"}}";
9
10        HttpRequest request = HttpRequest.newBuilder()
11            .uri(URI.create("https://api.linkupapi.com/v2/messages"))
12            .header("x-api-key", "YOUR_API_KEY")
13            .header("Content-Type", "application/json")
14            .POST(HttpRequest.BodyPublishers.ofString(payload))
15            .build();
16
17        HttpResponse<String> response = HttpClient.newHttpClient()
18            .send(request, HttpResponse.BodyHandlers.ofString());
19        System.out.println(response.body());
20    }
21}

Send iMessages

Send a real iMessage from a dedicated number with one API call.

Apple publishes no iMessage API for outreach, so teams that want the channel usually end up running an always-on Mac and keeping it alive. Here the line runs on managed infrastructure: you call POST /v2/messages with the line's account_id, and the message leaves as a blue bubble from your dedicated number, not from your personal Apple ID.

Replies, tapbacks and delivery receipts come back on your webhook with platform set to imessage, next to your LinkedIn, email and WhatsApp events, so one handler covers every channel. You can also send files and voice notes once the contact has replied, react with a tapback, show the typing indicator and send read receipts.

Every line is paced for you: a new line warms up over three weeks to 50 new conversations a day, and a contact who does not answer gets at most two follow-ups.

‍

1{
2  "success": true,
3  "data": {
4    "conversation_id": "+13231112233",
5    "message_id": "YOUR_MESSAGE_ID",
6    "delivery_status": "queued",
7    "send_kind": "new_contact"
8  },
9  "metadata": {
10    "action": "send",
11    "account_id": "YOUR_IMESSAGE_ACCOUNT_ID"
12  }
13}
Example result returned by the LinkupAPI iMessage API

Pulsor Agency

+1 323 111 2233 · iMessage

  • iMessage delivered
  • Reply received · webhook delivered
  • iMessage delivered
  • Reply received · webhook delivered

Privacy and security with no compromise.

Your users trust you with their accounts. Here is how we keep them safe.

Passwords never stored

We never keep your users' passwords. Sessions are encrypted, isolated per account and revocable at any time.

EU-hosted, GDPR & CCPA

Data is processed and hosted in the European Union. GDPR and CCPA compliant, with a data processing agreement on request.

Google-verified security

LinkupAPI passed Google's CASA security assessment and is a verified Gmail app. Same review, same standards for every channel.

Plug it into your AI assistant.

Every endpoint is a native tool for Claude, ChatGPT, Gemini, Mistral, Cursor and any other MCP client. Connect the LinkupAPI MCP server once and your assistant runs the calls on your accounts.

Our frequently asked questions.

LinkupAPI V2 - See what’s new

LinkedIn, email, WhatsApp and iMessage through one API. Unlimited accounts, one fixed price.

50
+

Endpoints

99.9
%

Uptime

< 3
s

Avg Response