Skip to Content
NovoDIDNovoDIDdocumentation
Public APIOperation referenceSMS

Read SMS history

History and eligible replies for SMS-enabled numbers.

GET /api/v1/sms/messages

Permission: sms:read

Required scopes

sms:read

Returns {messages: [...]} with id, direction, from, to, text, status and receivedAt. Optional didId/did must match; direction is inbound or outbound; limit 1–200, default 50. No page/cursor parameter. Only messages within the confirmed current SMS access window are eligible, never prior customers’ history. A mobile DID is not automatically SMS-enabled; inspect sms.enabled/canSend. Landlines do not support SMS. An empty result may mean no eligible messages.

While an account is under security review, reads and operations are blocked with HTTP 403 and code account_security_review, including previously issued tokens. Do not bypass the restriction or retry automatically. Access resumes after administrative release; other limits and restrictions still apply. Pending webhooks and events during the restriction are suppressed without automatic replay. Billing, due dates and expiration follow existing rules. Follow the review at https://novodid.com/seguranca/atendimento. Only the linked security ticket can be read and answered, including attachments, on the authenticated website. Other tickets and the public API remain blocked. The customer must wait for the first staff message and may send only one reply to each new staff message, including requested attachments.

Filters and parameters

?didId=1234&did=5511999999999&direction=inbound&limit=50

Success response (200)

{
  "messages": [
    {
      "id": "example-message",
      "direction": "inbound",
      "from": "5511988888888",
      "to": "5511999999999",
      "text": "Example message",
      "status": "received",
      "receivedAt": "2026-09-23T13:00:00.000Z"
    }
  ]
}

Error example

{
  "error": {
    "code": "insufficient_scope",
    "message": "Token sem permissão para esta operação."
  }
}

curl

curl -X GET \
  -H "Authorization: Bearer $NOVODID_API_TOKEN" \
  "https://novodid.com/api/v1/sms/messages?didId=1234&did=5511999999999&direction=inbound&limit=50"

Node

const response = await fetch("https://novodid.com/api/v1/sms/messages?didId=1234&did=5511999999999&direction=inbound&limit=50", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.NOVODID_API_TOKEN}`
  }
});
const payload = await response.json();

if (!response.ok) {
  throw new Error(payload.error?.message || "Erro na API NovoDID");
}

console.log({ status: response.status });

Python

import os
import requests

response = requests.get(
    "https://novodid.com/api/v1/sms/messages?didId=1234&did=5511999999999&direction=inbound&limit=50",
    headers={"Authorization": f"Bearer {os.environ['NOVODID_API_TOKEN']}"},
    timeout=30,
)

payload = response.json()
response.raise_for_status()
print({"status": response.status_code})

Go

package main

import (
    "fmt"
    "io"
    "net/http"
    "os"
)

func main() {
    req, err := http.NewRequest("GET", "https://novodid.com/api/v1/sms/messages?didId=1234&did=5511999999999&direction=inbound&limit=50", nil)
    if err != nil {
        panic(err)
    }

    req.Header.Set("Authorization", "Bearer "+os.Getenv("NOVODID_API_TOKEN"))

    res, err := http.DefaultClient.Do(req)
    if err != nil {
        panic(err)
    }
    defer res.Body.Close()

    _, _ = io.Copy(io.Discard, res.Body)
    if res.StatusCode >= 300 {
        panic(fmt.Sprintf("NovoDID API HTTP %d", res.StatusCode))
    }

    fmt.Println(res.StatusCode)
}

Rust

use reqwest::blocking::Client;
use std::env;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new();
    let response = client
        .get("https://novodid.com/api/v1/sms/messages?didId=1234&did=5511999999999&direction=inbound&limit=50")
        .bearer_auth(env::var("NOVODID_API_TOKEN")?)
        .send()?;

    let status = response.status();
    let _payload = response.text()?;
    if !status.is_success() {
        return Err(format!("NovoDID API HTTP {}", status).into());
    }

    println!("HTTP {}", status);
    Ok(())
}

PHP

<?php

$ch = curl_init("https://novodid.com/api/v1/sms/messages?didId=1234&did=5511999999999&direction=inbound&limit=50");

curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => [
    "Authorization: Bearer " . getenv("NOVODID_API_TOKEN")
  ],
]);

$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($response === false || $status >= 300) {
  throw new RuntimeException("NovoDID API HTTP " . $status);
}

echo $status . PHP_EOL;

Ruby

require "net/http"

uri = URI("https://novodid.com/api/v1/sms/messages?didId=1234&did=5511999999999&direction=inbound&limit=50")
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer #{ENV.fetch("NOVODID_API_TOKEN")}"

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
  http.request(request)
end

raise "NovoDID API HTTP #{response.code}" unless response.is_a?(Net::HTTPSuccess)

puts response.code

C#

using System.Net.Http.Headers;

using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Get, "https://novodid.com/api/v1/sms/messages?didId=1234&did=5511999999999&direction=inbound&limit=50");

request.Headers.Authorization = new AuthenticationHeaderValue(
    "Bearer",
    Environment.GetEnvironmentVariable("NOVODID_API_TOKEN")
);

using var response = await client.SendAsync(request);
var payload = await response.Content.ReadAsStringAsync();

response.EnsureSuccessStatusCode();
Console.WriteLine(response.StatusCode);

On this page