curl --request PUT \
--url https://api.reply.io/v3/api-keys/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"scopes": [
"<string>"
]
}
'import requests
url = "https://api.reply.io/v3/api-keys/{id}"
payload = {
"name": "<string>",
"scopes": ["<string>"]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({name: '<string>', scopes: ['<string>']})
};
fetch('https://api.reply.io/v3/api-keys/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.reply.io/v3/api-keys/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'name' => '<string>',
'scopes' => [
'<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.reply.io/v3/api-keys/{id}"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"scopes\": [\n \"<string>\"\n ]\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.put("https://api.reply.io/v3/api-keys/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"scopes\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.reply.io/v3/api-keys/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"scopes\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"id": 123,
"type": "user",
"hint": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"scopes": [
"<string>"
],
"name": "<string>",
"expiresAt": "2023-11-07T05:31:56Z"
}{
"title": "Bad Request",
"status": 400,
"detail": "'tasks:*' is not a scope this route can grant.",
"code": "apiKey.invalidScope"
}{
"title": "Unauthorized",
"status": 401,
"detail": "Authentication credentials are missing or invalid."
}{
"title": "Forbidden",
"status": 403,
"detail": "This API key does not hold 'inbox:read', so it cannot leave a key with it.",
"code": "apiKey.scopeNotHeld"
}{
"title": "Not Found",
"status": 404,
"detail": "API key not found.",
"code": "apiKey.notFound"
}{
"title": "Too Many Requests",
"status": 429,
"detail": "API calls quota exceeded! maximum admitted 100 per 1m."
}Update an API key
Coming soon. This endpoint will be available by mid November 2026.
api-keys:write scope (or a broader one that includes it).
Replace a key’s name and scopes. A field left out is cleared: no name, no scopes. A scope already on the key stays valid here, even a wildcard; a new one must be an exact scope.
A key’s expiry is set when it is created and cannot change here; a body that sends expiresAt, null included, answers 400.
An API key may change a key only if the key ends no wider than the caller. An API key that has an expiry cannot add a scope to a key that expires later or never.
curl --request PUT \
--url https://api.reply.io/v3/api-keys/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"scopes": [
"<string>"
]
}
'import requests
url = "https://api.reply.io/v3/api-keys/{id}"
payload = {
"name": "<string>",
"scopes": ["<string>"]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({name: '<string>', scopes: ['<string>']})
};
fetch('https://api.reply.io/v3/api-keys/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.reply.io/v3/api-keys/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'name' => '<string>',
'scopes' => [
'<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.reply.io/v3/api-keys/{id}"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"scopes\": [\n \"<string>\"\n ]\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.put("https://api.reply.io/v3/api-keys/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"scopes\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.reply.io/v3/api-keys/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"scopes\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"id": 123,
"type": "user",
"hint": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"scopes": [
"<string>"
],
"name": "<string>",
"expiresAt": "2023-11-07T05:31:56Z"
}{
"title": "Bad Request",
"status": 400,
"detail": "'tasks:*' is not a scope this route can grant.",
"code": "apiKey.invalidScope"
}{
"title": "Unauthorized",
"status": 401,
"detail": "Authentication credentials are missing or invalid."
}{
"title": "Forbidden",
"status": 403,
"detail": "This API key does not hold 'inbox:read', so it cannot leave a key with it.",
"code": "apiKey.scopeNotHeld"
}{
"title": "Not Found",
"status": 404,
"detail": "API key not found.",
"code": "apiKey.notFound"
}{
"title": "Too Many Requests",
"status": 429,
"detail": "API calls quota exceeded! maximum admitted 100 per 1m."
}Authorizations
Authenticate every request with a Bearer token. Pass your Reply API key in the
Authorization header:
Authorization: Bearer <your-api-key>
Get your API key from the Reply dashboard: Settings → API Key.
Path Parameters
The key's id.
Body
Response
The key as it now stands.
The key's id.
Who the key belongs to.
user, team, organization The start and end of the key, as Settings shows it.
When the key was created.
The scopes as stored, which may include wildcards set in Settings.
The key's name.
When the key stops working, or null if it never does.