Manual · Conectar otras aplicaciones
Usar la API
La API deja que otra aplicación haga por ti lo mismo que haces en el tablero: publicar, reemplazar una versión, compartir, quitar el acceso, archivar y ver quién abrió. Trabaja a tu nombre, con lo que le permitas, y te avisa por correo de lo delicado.
Tu llave
En Cuenta → API, Crear llave: ponle un nombre que te diga dónde la vas a usar («Prospector», «Claude Code») y marca lo que puede hacer. Para una integración que solo consulta, deja marcada solo la primera casilla.
| Permiso | Qué deja hacer |
|---|---|
documentos:leer |
Ver la lista y el detalle, con los correos de las personas a las que compartiste |
documentos:publicar |
Publicar documentos y reemplazar versiones |
documentos:compartir |
Compartir a tu nombre y recibir las ligas |
documentos:revocar |
Quitarle el acceso a una persona |
documentos:archivar |
Quitarle el acceso a todos y archivar; te avisamos y lo puedes deshacer |
Tres cosas que conviene saber:
- La llave se muestra una sola vez. Si la pierdes, revócala y crea otra.
- Para crearla tienes que haber entrado hace poco. Si tu sesión es de hace días, te mandamos una liga a tu correo y la creas desde esa sesión nueva. Así, alguien que tuviera tu sesión abierta en otro lado no puede fabricarse una.
- Actúa como tú, sobre todos los documentos de tu cuenta, también los que publicó otra persona de tu equipo. No puede administrar la cuenta ni crear otras llaves. Vence a los 12 meses.
Cada vez que se crea o se revoca una llave te llega un correo. Si recibes uno que no esperabas, revócala y en Cuenta usa Cerrar mis otras sesiones.
Probarla
La llave va en la cabecera Authorization:
curl https://api.cartaventa.com/v1/yo -H "Authorization: Bearer cv_live_…"
Responde quién eres, tu cuenta y los permisos de la llave. Si da 401, la llave está mal copiada, se revocó o venció.
Las rutas
| Ruta | Permiso | Qué hace |
|---|---|---|
GET /v1/yo |
leer | Quién es esta llave |
GET /v1/documentos |
leer | Tus documentos, de 20 en 20 (?estado=activo|archivado|todos&limite=…&cursor=…) |
POST /v1/documentos |
publicar | Publica un documento nuevo; responde 201 |
GET /v1/documentos/{id} |
leer | El detalle: versiones, y cada persona con su estado y sus aperturas |
POST /v1/documentos/{id}/versiones |
publicar | Versión nueva, misma liga |
POST /v1/documentos/{id}/compartir |
compartir | Comparte y devuelve la liga de cada persona |
POST /v1/documentos/{id}/revocar |
revocar | Le quita el acceso a una persona |
POST /v1/documentos/{id}/revocar-todos |
archivar | Le quita el acceso a todos |
POST /v1/documentos/{id}/archivar |
archivar | Archiva el documento |
{id} es el public_id que devuelven publicar y la lista; es el mismo de la liga del documento. Las fechas salen en UTC con Z, y lo que lista viene en { datos, siguiente_cursor }: con siguiente_cursor en null ya no hay más.
Publicar y reemplazar
El HTML sigue las mismas reglas que en el tablero (Cómo debe ser el HTML), pasa por la misma moderación y comparte el tope de 30 publicaciones por hora. Se manda de una de tres formas:
El archivo tal cual, hasta 5 MB, con el título en la dirección. Es la forma para archivos grandes:
curl -X POST "https://api.cartaventa.com/v1/documentos?titulo=Propuesta%20Acme" \
-H "Authorization: Bearer cv_live_…" \
-H "Content-Type: text/html" \
--data-binary @propuesta.html
Como formulario, con los campos titulo y archivo, también hasta 5 MB:
curl -X POST https://api.cartaventa.com/v1/documentos \
-H "Authorization: Bearer cv_live_…" \
-F titulo="Propuesta Acme" -F archivo=@propuesta.html
En JSON, { "titulo": "…", "html": "…" }, hasta 512 KB. Es lo cómodo si el HTML ya está en una variable.
En los tres puedes pedir restriccion: estandar (la de siempre) o estricta, donde cada persona entra con un código que le llega a su correo. Para integraciones recomendamos estricta: la liga que te devuelve compartir solo identifica a la persona, no abre por sí sola. Va en la dirección (&restriccion=estricta), como campo del formulario o en el JSON.
Para reemplazar, lo mismo contra /v1/documentos/{id}/versiones, sin título. Responde la versión nueva y cuántas personas verán el cambio la próxima vez que abran.
Compartir
curl -X POST https://api.cartaventa.com/v1/documentos/{id}/compartir \
-H "Authorization: Bearer cv_live_…" \
-H "Content-Type: application/json" \
-d '{"destinatarios": [{"nombre": "Juan Pérez", "correo": "juan@acme.com"}], "mensaje": "Te comparto la propuesta."}'
- Cada destinatario lleva
nombre,correootelefono(su WhatsApp), o varios. En un documento estricto el correo es obligatorio. - Una persona que no cumple no tira la llamada: va a
invalidoscon su posición, su código y el motivo, y las demás se comparten. - Con
"enviar_correo": falseno le mandamos nada a nadie: tu aplicación recibe las ligas y las manda por su lado. - La respuesta trae
creados,repetidos,invalidosyfallidos, y cada persona con su liga. Es la única respuesta de la API que trae ligas; guárdalas como guardas una contraseña. repetidosson personas que ya tenían acceso: no les llega otro correo, pero reciben una liga nueva para que siempre tengas la vigente. La que le habías pedido antes a la API deja de servir; las del correo y las que copiaste en el tablero, no.fallidosson personas que quedaron dadas de alta pero cuyo correo no salió: su liga viene ahí para que la mandes tú.
Topes, contra un asistente engañado por un correo malicioso: 5 personas y 2 empresas distintas (dominios de correo) por llamada; 20 personas al día por usuario y 60 por cuenta. Cuentan también las repetidas y las que no traen correo. Para más, compártelo desde el tablero.
Cada llamada que comparte te manda un correo con a quién se compartió. Si no fuiste tú, revoca la llave.
Quitar el acceso y archivar
POST …/revocarcon{ "destinatario_id": "…" }(el de la respuesta de compartir o del detalle) o{ "correo": "…" }. Repetirlo no hace daño. Una misma llave le quita el acceso a máximo 10 personas por hora.POST …/revocar-todosle quita el acceso a todos los que lo tenían.POST …/archivarapaga el documento; si ya estaba archivado, responde igual.
Revocar a todos y archivar se pueden deshacer desde el correo: en cuanto pasan te llega un aviso con un botón Deshacer que funciona sin iniciar sesión, durante 72 horas (revocar a todos) o 7 días (archivar). Devuelve el acceso con las mismas ligas de antes y a tus clientes no les llega nada. Por la API no hay desarchivar: eso se hace en el tablero.
Si una llave hace cuatro de estas cosas en 24 horas —archivar, quitarle el acceso a todos o a una persona—, en vez de un correo por cada una te llega uno solo con un botón que deshace todo lo que hizo esa llave desde entonces y la corta.
Si el documento es de otra persona de tu equipo, a ella le llega además su propio aviso, con su propio botón Deshacer, con la misma regla: tres sueltos y, a la cuarta, uno solo que deshace todo lo de sus documentos. Su botón sigue sirviendo aunque desactiven a quien creó la llave, y cuando alguien deshace, la confirmación les llega a los dos.
Reintentos
Repetir una escritura no la hace dos veces. Si la misma llave manda la misma petición dentro de 60 segundos, sin otra escritura en medio, recibe la respuesta original —con las mismas ligas, sin volver a mandar correos— y la cabecera Idempotent-Replayed: true. Quitar el acceso, revocar a todos y archivar no necesitan esa ventana: repetirlos ya no cambia nada. Para reintentar más tarde sin duplicar, manda tu propia clave:
-H "Idempotency-Key: compartir-propuesta-acme-juan"
Con ella la misma operación se reconoce durante 24 horas. Usa una clave distinta para cada operación distinta: la misma clave con otro cuerpo da error.
Límites
| Qué | Límite |
|---|---|
Consultas (GET) |
120 por minuto por llave |
| Publicar o reemplazar | 30 por hora por usuario, en cualquier superficie |
| Compartir | 5 personas y 2 dominios por llamada; 20 al día por usuario, 60 por cuenta |
Cambios de cualquier tipo (POST) |
60 por minuto por llave |
| Quitarle el acceso a una persona | 10 por hora por llave |
| Llaves | 10 vivas y 5 creadas por hora por usuario |
Al topar, 429 con limite_ritmo, el nombre del límite y, cuando se sabe, la cabecera Retry-After.
Avisos que te llegan
Además de los de compartir y de archivar o revocar, te escribimos si una llave abre el detalle de más de 25 documentos en una hora: barrer el catálogo es la firma de un asistente al que le metieron instrucciones. Si es lo que le pediste, no hagas nada.
Si tu cuenta no debe sacar los correos de tus clientes hacia otras aplicaciones, el propietario puede encender en Cuenta → API «No exponer correos de destinatarios por API»: el detalle los muestra como j***@acme.com y sin nombre.
Errores
Todo error llega en application/problem+json:
{
"type": "https://cartaventa.com/guias/usar-la-api#limite_ritmo",
"title": "Se topó un límite de ritmo",
"status": 429,
"codigo": "limite_ritmo",
"mensaje": "Subiste 30 documentos o versiones en la última hora…",
"limite": "publicar_por_hora"
}
codigo no cambia nunca; el texto de mensaje sí puede cambiar. Los datos para corregirse, como la regla de moderación o el límite, vienen junto, al mismo nivel.
moderacion_bloqueada
La moderación bloqueó el documento. reglas dice cuál regla disparó y por qué; corrige el HTML y vuelve a mandarlo. Ver Cuando un documento no se publica.
html_invalido
No es un HTML que Cartaventa acepte: no es HTML, trae algo prohibido o una imagen rota. El mensaje dice qué.
html_demasiado_grande
El documento pesa demasiado. Por JSON caben 512 KB; como archivo o formulario, 5 MB, y lo que se guarda, ya con las imágenes comprimidas, tampoco pasa de 5 MB.
cuota_paginas_activas
Tu plan llegó a su límite de documentos compartidos. Archiva uno que ya no uses o sube de plan; lo ya compartido sigue abriendo.
slug_sin_confirmar
La cuenta todavía no confirma su subdominio. Entra al tablero una vez y confírmalo.
correo_invalido
Ese correo no parece válido. Al quitar el acceso, "todos" también da este error: para eso está revocar-todos.
demasiados_destinatarios
Más de 5 personas en una sola llamada. Pártelas, o compártelo desde el tablero.
demasiados_dominios
Personas de más de 2 empresas distintas en una sola llamada. Pártelas por empresa.
correo_requerido_en_estricta
El documento es estricto y esa persona no trae correo: sin él no le puede llegar su código.
sin_datos
Esa persona no trae ni nombre, ni correo, ni WhatsApp, o no viene como objeto.
telefono_invalido
Ese WhatsApp no parece un número: 10 dígitos, o el número completo con su lada (+52…).
documento_archivado
El documento está archivado y esa acción no aplica. Desarchívalo en el tablero.
documento_no_encontrado
Ese documento no existe, es de otra cuenta, o está archivado y la acción no aplica a archivados. Las tres respuestas son idénticas a propósito.
destinatario_no_encontrado
Esa persona no está entre los destinatarios del documento.
limite_ritmo
Se topó un límite; limite dice cuál y Retry-After, cuándo reintentar. Ver Límites.
organizacion_suspendida
La cuenta está suspendida. Escríbenos.
entrada_invalida
Falta un dato o no tiene la forma esperada; campo dice cuál. También si el cuerpo no es JSON válido.
no_autenticado
Falta la llave, está mal copiada, se revocó o venció. Siempre la misma respuesta, sin decir cuál de las cuatro.
permiso_insuficiente
La llave no tiene el permiso de esa ruta; la cabecera WWW-Authenticate dice cuál falta. Crea otra llave con ese permiso.
ruta_no_encontrada
Esa ruta o ese método no existen. Las rutas viven bajo /v1.
error_interno
Algo falló de nuestro lado y ya quedó registrado. Reintenta en un momento; si sigue, escríbenos con la hora.
tipo_no_soportado
Ese Content-Type no se acepta en esa ruta. Publicar y reemplazar aceptan text/html, multipart/form-data o application/json; compartir y revocar, application/json.
cuerpo_demasiado_grande
El cuerpo pasa de 512 KB en una ruta que no recibe documentos.
solicitud_en_curso
Esa misma petición todavía se está procesando. Espera unos segundos y reintenta: recibirás el resultado de la primera.
clave_idempotencia_reusada
Esa Idempotency-Key ya se usó con otra petición. Usa una clave nueva para cada operación distinta.
¿Algo que no cuadra? Escríbenos por WhatsApp.
¿Te faltó algo en esta guía? Escríbenos por WhatsApp y la corregimos. También puedes leerla en Markdown —para pegársela a tu IA— en /guias/usar-la-api.md.