curl --request POST \
--url https://api.revem.ai/contacts/public/v1 \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"phone_number": "+56912345678",
"first_name": "Camila",
"last_name": "Rojas",
"email": "camila@ejemplo.cl",
"programa": "Premium"
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
phone_number: '+56912345678',
first_name: 'Camila',
last_name: 'Rojas',
email: 'camila@ejemplo.cl',
programa: 'Premium'
})
};
fetch('https://api.revem.ai/contacts/public/v1', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.revem.ai/contacts/public/v1"
payload = {
"phone_number": "+56912345678",
"first_name": "Camila",
"last_name": "Rojas",
"email": "camila@ejemplo.cl",
"programa": "Premium"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"ok": true,
"id": "3f2b6c1e-8d4a-4f0b-9c2e-7a1d5e6f8b90",
"created": true,
"warnings": []
}{
"ok": false,
"error": "body/phone_number Invalid input: expected string, received undefined"
}{
"error": "Unauthorized",
"message": "Invalid API key"
}{
"error": "<string>",
"ok": false,
"message": "<string>",
"unknownAttributes": [
"<string>"
]
}{
"ok": false,
"error": "Conflict",
"message": "El teléfono pertenece a un contacto en la papelera; restáuralo o elimínalo desde Contactos"
}{
"ok": false,
"error": "Unprocessable Entity",
"message": "Atributos sin definición: \"embcodigo\"",
"unknownAttributes": [
"embcodigo"
]
}{
"ok": false,
"error": "Too many requests. Retry in 1 minute."
}Crear o actualizar un contacto
Escribe un contacto identificado por su teléfono: si ya existe uno con ese número se actualiza, si no se crea. Una clave ausente deja el valor guardado como está, así que una solicitud parcial es una actualización parcial.
Los atributos personalizados van al mismo nivel que los campos fijos, identificados por su nombre en Revem. Un nombre sin definición responde 422 con la lista en unknownAttributes; un valor que no calza con el tipo declarado también responde 422.
Un contacto que estaba en la papelera, o que pertenece al simulador, sigue siendo dueño de su número: escribirle responde 409 y se resuelve desde la app.
curl --request POST \
--url https://api.revem.ai/contacts/public/v1 \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"phone_number": "+56912345678",
"first_name": "Camila",
"last_name": "Rojas",
"email": "camila@ejemplo.cl",
"programa": "Premium"
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
phone_number: '+56912345678',
first_name: 'Camila',
last_name: 'Rojas',
email: 'camila@ejemplo.cl',
programa: 'Premium'
})
};
fetch('https://api.revem.ai/contacts/public/v1', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.revem.ai/contacts/public/v1"
payload = {
"phone_number": "+56912345678",
"first_name": "Camila",
"last_name": "Rojas",
"email": "camila@ejemplo.cl",
"programa": "Premium"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"ok": true,
"id": "3f2b6c1e-8d4a-4f0b-9c2e-7a1d5e6f8b90",
"created": true,
"warnings": []
}{
"ok": false,
"error": "body/phone_number Invalid input: expected string, received undefined"
}{
"error": "Unauthorized",
"message": "Invalid API key"
}{
"error": "<string>",
"ok": false,
"message": "<string>",
"unknownAttributes": [
"<string>"
]
}{
"ok": false,
"error": "Conflict",
"message": "El teléfono pertenece a un contacto en la papelera; restáuralo o elimínalo desde Contactos"
}{
"ok": false,
"error": "Unprocessable Entity",
"message": "Atributos sin definición: \"embcodigo\"",
"unknownAttributes": [
"embcodigo"
]
}{
"ok": false,
"error": "Too many requests. Retry in 1 minute."
}Authorizations
La API key de tu organización, con la forma rvm_<prefijo>.<secreto>, enviada como Authorization: Bearer rvm_…. Revem la emite y sólo se muestra una vez; si la pierdes se reemplaza, no se recupera.
Body
Cualquier otra clave del cuerpo se interpreta como un atributo personalizado del contacto, identificado por su nombre tal como está definido en Revem. Un nombre que no existe responde 422; se aceptan hasta 100 atributos por solicitud.
Teléfono del contacto. Se recomienda formato E.164 (+56912345678); otras grafías se normalizan al guardar. Es la identidad: si ya existe un contacto con este número, se actualiza; si no, se crea.
1Nombre. Si se omite, el valor guardado no cambia.
Apellido. Si se omite, el valor guardado no cambia.
Si otro contacto del mismo tenant ya tiene este email, se conserva el resto de la solicitud y se informa en warnings.
Response
Contacto creado o actualizado.
Identificador del contacto creado o actualizado. Guárdalo: es la clave estable para PATCH /{id} y para webchat.
true si la solicitud creó el contacto; false si el teléfono ya existía y se actualizó.
Avisos sobre una solicitud que SÍ escribió. Hoy el único caso es un email que no se guardó porque pertenece a otro contacto.
