Documentación para desarrolladores

API REST

Conecte los sistemas propios de su organización con Melora Connect: lea y actualice miembros, lea eventos con sus inscripciones, cree eventos en borrador, lea facturas de cuotas y suscriba URL de webhooks.

Resumen

La API responde JSON por HTTPS. Cada ruta de esta página empieza con esta URL base:

https://app.meloraconnect.com/api/public/v1

Para enterarse de los cambios en el momento en que ocurren, use los webhooks. Para usar las mismas operaciones desde un cliente MCP, consulte el servidor MCP.

Quién puede usarla

La API está incluida en todos los planes de Melora Connect. Las claves las crea en Melora Connect el personal que puede administrar la configuración de la organización. Si la API deja de formar parte del plan de la organización, sus claves dejan de funcionar en la siguiente solicitud y vuelven a funcionar cuando el plan la incluya de nuevo, salvo que se hayan revocado o hayan vencido.

Autenticación

Cada solicitud lleva una clave de API en el encabezado Authorization, después de la palabra Bearer:

Authorization: Bearer melora_YOUR_KEY

Crear una clave

  1. En Melora Connect, abra Settings y luego la pestaña API keys.
  2. Ponga a la clave el nombre del sistema que la usará, elija sus permisos y cuándo vence, y haga clic en Make key.
  3. Copie la clave y guárdela en su servidor. Se muestra una sola vez.

Sobre las claves

  • Una clave pertenece a una sola organización. Cada solicitud actúa en esa organización y en ninguna otra, y nada en una solicitud puede elegir otra. Un registro de otra organización responde 404, como si no existiera.
  • Melora Connect guarda solo una huella de la clave (un hash SHA-256), así que no puede volver a mostrarla. Guárdela como una contraseña, en su servidor, nunca en una página web ni en una aplicación móvil.
  • Las claves empiezan con melora_ seguido de 43 caracteres. La pestaña API keys muestra los primeros 15 caracteres de cada clave, para distinguirlas, y cuándo se usó cada una por última vez.
  • Una clave puede vencer a los 30, 90 o 365 días, o nunca, y puede revocarse en cualquier momento con Revoke. Una clave revocada o vencida se rechaza desde la siguiente solicitud.
  • Una organización puede tener hasta 25 claves activas (las revocadas y las vencidas no cuentan). Cree una clave por sistema, para poder revocar una sin afectar a las demás.
  • Los permisos de una clave se fijan al crearla. Para cambiarlos, cree una clave nueva y revoque la anterior.

Permisos

Cada clave lleva solo los permisos elegidos para ella, de entre los mismos permisos que usan los roles del personal en Melora Connect. Quien crea una clave solo puede darle permisos que tiene. Una solicitud que la clave no permite responde 403 con el código permission_denied.

Permiso de la claveQué permite
members.readLeer miembros: el padrón y un miembro.
members.writeAgregar miembros, cambiar los campos de miembro indicados y dar de baja a un miembro del email de marketing de la organización.
events.readLeer eventos, y un evento con sus inscripciones.
events.manageCrear eventos en borrador.
members.billing.readLeer facturas de cuotas.
settings.manageSuscribir y cancelar URL de webhooks (lo que usa Zapier).

Versiones

La versión está en la ruta, /v1. Dentro de v1, Melora Connect solo agrega: endpoints nuevos, parámetros opcionales nuevos y campos nuevos en las respuestas, así que su código debe ignorar los campos que no conoce. Todo lo que rompería una integración que funciona llega como una versión nueva, y v1 sigue funcionando al mismo tiempo.

Límites

  • Cada clave puede hacer 120 solicitudes cada 60 segundos. Pasado ese número, la respuesta es 429 con un encabezado Retry-After en segundos.
  • Sumando todas sus claves, una organización puede hacer 600 solicitudes cada 60 segundos. Pasado ese número, todas las claves reciben 429 hasta que avance la ventana.
  • Una dirección que presenta más de 30 claves desconocidas en 10 minutos también recibe 429.
  • El cuerpo de una solicitud es JSON, enviado con Content-Type: application/json, y puede tener hasta 64 KB. Uno más grande recibe 413 (payload_too_large) sin leerse.

Listas y formatos

Cada lista acepta page (desde 1) y per_page (de 1 a 100, 50 por defecto) y responde con data, page, per_page y has_more. Pida la página siguiente mientras has_more sea verdadero.

Los miembros llegan del cambio más antiguo al más reciente. Para mantener una copia al día, envíe el updated_at más reciente que tenga como updated_since: vuelven los registros cambiados en ese momento o después. Los eventos llegan por hora de inicio, y las facturas de cuotas de la más antigua a la más reciente.

Las horas están en ISO 8601 con zona horaria (por ejemplo 2026-11-12T08:00:00-05:00), las fechas en YYYY-MM-DD, los importes en centavos y los id son UUID. Un id que no es un UUID responde 404.

Lista de endpoints

Cada endpoint, el permiso que necesita su clave y qué hace. Cada uno se explica más abajo con un ejemplo.

SolicitudPermiso requeridoQué hace
GET /membersmembers.readListar miembros, del cambio más antiguo al más reciente.
GET /members/{id}members.readUn miembro.
POST /membersmembers.writeAgregar un miembro. Responde 201 con el miembro nuevo.
PATCH /members/{id}members.writeCambiar los campos que envíe de un miembro.
POST /members/{id}/email-preferencesmembers.writeDa de baja a un miembro del email de marketing de la organización, como lo hace el enlace de baja de una campaña. Responde 200.
GET /eventsevents.readListar eventos por hora de inicio.
GET /events/{id}events.readUn evento con sus inscripciones.
POST /eventsevents.manageCrear un evento en borrador. Responde 201 con el evento.
GET /dues-invoicesmembers.billing.readListar facturas de cuotas, de la más antigua a la más reciente.
POST /webhookssettings.manageSuscribir una URL de webhook a eventos. Es lo que usa Zapier.
DELETE /webhooks/{id}settings.manageCancelar la suscripción de un webhook suscrito por la API.

GET /api/public/v1/members

Listar miembros, del cambio más antiguo al más reciente.

Permiso requerido: members.read

Parámetros

  • status (opcional): active, pending, lapsed, expired, suspended, archived o at_risk.
  • membership_type_id (opcional): el id de uno de los tipos de membresía de la organización.
  • updated_since (opcional): una fecha y hora con zona horaria. Solo los miembros cambiados en ese momento o después.
  • email_marketing_opt_out (opcional): true lista solo los miembros que se han dado de baja del email de marketing de la organización, false solo los demás.
  • page y per_page (opcionales): vea Listas y formatos.

Cada miembro tiene los campos de abajo. custom_fields contiene los campos de miembro propios de la organización, como clave del campo y valor.

email_marketing_opt_out es true cuando el miembro se ha dado de baja del email de marketing de la organización, y email_marketing_opted_out_at indica cuándo (null mientras no lo haya hecho). Es la misma lectura que usan las campañas de Melora Connect: un enlace de baja o una queja desde la dirección, para esta organización o para todo Melora Connect, o el interruptor de email del miembro para la organización apagado (también desde una audiencia de Mailchimp conectada). Un rebote no es una baja, y la baja de una organización nunca da de baja al miembro de otra. Una baja no cambia updated_at: siga los webhooks member.unsubscribed y member.resubscribed, y concilie de vez en cuando con email_marketing_opt_out=true.

Campos: id, name, first_name, last_name, email, company, title, industry, phone, website, linkedin_url, city, state, zip, bio, status, membership_type_id, membership_category, tier, join_date, renewal_date, tags, show_in_directory, chapter_id, created_at, updated_at, custom_fields, email_marketing_opt_out, email_marketing_opted_out_at.

Solicitud de ejemplo

curl "https://app.meloraconnect.com/api/public/v1/members?status=active&per_page=50&page=1" \
  -H "Authorization: Bearer $MELORA_API_KEY"

Respuesta de ejemplo, HTTP 200

{
  "data": [
    {
      "id": "8d2c6f0e-3f59-4a53-9c0e-0f6f5b3a1b21",
      "name": "Ana Ruiz",
      "first_name": "Ana",
      "last_name": "Ruiz",
      "email": "ana@example.org",
      "company": "Ruiz Consulting",
      "status": "active",
      "membership_type_id": "0b7a3c62-7f3e-4d7c-8a57-25a1c0a9d7e4",
      "join_date": "2026-03-02",
      "renewal_date": "2027-03-02",
      "tags": ["board"],
      "updated_at": "2026-09-28T14:03:11.402Z",
      "email_marketing_opt_out": false,
      "email_marketing_opted_out_at": null
    }
  ],
  "page": 1,
  "per_page": 50,
  "has_more": false
}

GET /api/public/v1/members/{id}

Un miembro.

Permiso requerido: members.read

Parámetros

  • id (en la ruta): el id del miembro.

El miembro tiene los mismos campos que en la lista. Un miembro que no existe, o que pertenece a otra organización, responde 404.

Solicitud de ejemplo

curl "https://app.meloraconnect.com/api/public/v1/members/8d2c6f0e-3f59-4a53-9c0e-0f6f5b3a1b21" \
  -H "Authorization: Bearer $MELORA_API_KEY"

Respuesta de ejemplo, HTTP 200

{
  "data": {
    "id": "8d2c6f0e-3f59-4a53-9c0e-0f6f5b3a1b21",
    "name": "Ana Ruiz",
    "first_name": "Ana",
    "last_name": "Ruiz",
    "email": "ana@example.org",
    "company": "Ruiz Consulting",
    "status": "active",
    "membership_type_id": "0b7a3c62-7f3e-4d7c-8a57-25a1c0a9d7e4",
    "join_date": "2026-03-02",
    "renewal_date": "2027-03-02",
    "tags": [
      "board"
    ],
    "updated_at": "2026-09-28T14:03:11.402Z",
    "email_marketing_opt_out": false,
    "email_marketing_opted_out_at": null,
    "custom_fields": {
      "member_since_year": 2019
    }
  }
}

POST /api/public/v1/members

Agregar un miembro. Responde 201 con el miembro nuevo.

Permiso requerido: members.write

Parámetros

  • email (obligatorio): un miembro por dirección de correo en la organización.
  • name, o first_name y last_name (obligatorio): al menos uno de ellos.
  • status (opcional): active, el valor por defecto, o pending, lapsed, expired, suspended o archived.
  • join_date y renewal_date (opcionales): fechas en YYYY-MM-DD.
  • membership_type_id (opcional): uno de los tipos de membresía de la organización.
  • También opcionales: company, title, industry, phone, website, linkedin_url, city, state, zip, bio y tags (una lista de palabras).
  • start_welcome_drips (opcional): true para iniciar las campañas de New member de la organización para un miembro activo.

Un miembro activo ocupa uno de los lugares de miembros activos del plan; cuando no queda ninguno, la respuesta es 403 limit_reached. Un correo que ya pertenece a un miembro de la organización responde 409 conflict, con el id de ese miembro en details.existing_member_id.

Un miembro agregado por la API no entra en ninguna campaña automática de correo de la organización, así que un sistema que copia un padrón entero no le envía una bienvenida a todos. Para dar la bienvenida a un miembro nuevo, envíe start_welcome_drips como true: un miembro activo entra entonces en las campañas de New member de la organización, igual que un miembro agregado a mano, y la respuesta incluye welcome_drips.enrolled, el número de campañas en las que entró (0 para un miembro que no está activo).

phone debe tener de 7 a 15 dígitos y se guarda como sus dígitos, conservando un + inicial (+1 (703) 555-0142 se guarda como +17035550142). website debe ser una dirección http o https y se guarda con su esquema (se agrega https:// si no se envía ninguno). linkedin_url debe ser una dirección https en linkedin.com. Un valor vacío borra el campo. Un valor no válido responde 422 validation_failed, y details nombra el campo.

Solicitud de ejemplo

curl -X POST "https://app.meloraconnect.com/api/public/v1/members" \
  -H "Authorization: Bearer $MELORA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"first_name":"Ana","last_name":"Ruiz","email":"ana@example.org","company":"Ruiz Consulting","status":"active","renewal_date":"2027-03-02","tags":["board"]}'

Respuesta de ejemplo, HTTP 201

{
  "data": {
    "id": "8d2c6f0e-3f59-4a53-9c0e-0f6f5b3a1b21",
    "name": "Ana Ruiz",
    "first_name": "Ana",
    "last_name": "Ruiz",
    "email": "ana@example.org",
    "company": "Ruiz Consulting",
    "status": "active",
    "membership_type_id": "0b7a3c62-7f3e-4d7c-8a57-25a1c0a9d7e4",
    "join_date": "2026-03-02",
    "renewal_date": "2027-03-02",
    "tags": [
      "board"
    ],
    "updated_at": "2026-09-28T14:03:11.402Z",
    "email_marketing_opt_out": false,
    "email_marketing_opted_out_at": null,
    "custom_fields": {}
  }
}

PATCH /api/public/v1/members/{id}

Cambiar los campos que envíe de un miembro.

Permiso requerido: members.write

Parámetros

  • id (en la ruta): el id del miembro.
  • Cuerpo: cualquiera de name, first_name, last_name, email, company, title, industry, phone, website, linkedin_url, city, state, zip, bio, tags, membership_type_id, status y renewal_date. Envíe al menos uno.

Cualquier otro campo se rechaza con 422. El estado at_risk lo calcula Melora Connect a partir de la actividad del miembro y no se puede fijar, y los puntos, la participación y los datos de inicio de sesión no se pueden cambiar. membership_type_id debe ser uno de los tipos de membresía de la organización.

Activar a un miembro ocupa uno de los lugares de miembros activos del plan. Si el estado del miembro cambió mientras se procesaba su solicitud, la respuesta es 409 conflict: lea el miembro e intente de nuevo.

phone, website y linkedin_url se verifican igual que al agregar un miembro. Envíe solo los campos que cambia: un registro más antiguo puede tener un teléfono que no pasa las verificaciones de hoy, así que reenviar el registro completo puede rechazarse.

Solicitud de ejemplo

curl -X PATCH "https://app.meloraconnect.com/api/public/v1/members/8d2c6f0e-3f59-4a53-9c0e-0f6f5b3a1b21" \
  -H "Authorization: Bearer $MELORA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"phone":"+1 555 0100","status":"lapsed"}'

Respuesta de ejemplo, HTTP 200

{
  "data": {
    "id": "8d2c6f0e-3f59-4a53-9c0e-0f6f5b3a1b21",
    "name": "Ana Ruiz",
    "first_name": "Ana",
    "last_name": "Ruiz",
    "email": "ana@example.org",
    "company": "Ruiz Consulting",
    "status": "lapsed",
    "membership_type_id": "0b7a3c62-7f3e-4d7c-8a57-25a1c0a9d7e4",
    "join_date": "2026-03-02",
    "renewal_date": "2027-03-02",
    "tags": [
      "board"
    ],
    "updated_at": "2026-10-04T10:12:45.118Z",
    "email_marketing_opt_out": false,
    "email_marketing_opted_out_at": null,
    "phone": "+15550100"
  }
}

POST /api/public/v1/members/{id}/email-preferences

Da de baja a un miembro del email de marketing de la organización, como lo hace el enlace de baja de una campaña. Responde 200.

Permiso requerido: members.write

Parámetros

  • id (en la ruta): el id del miembro.
  • Cuerpo: email_marketing_opt_out (obligatorio), true. Cualquier otro campo se rechaza con 422.

La próxima campaña de la organización deja fuera al miembro, su interruptor de email para la organización se apaga y sale de sus listas de boletines. El email de otras organizaciones no se toca. La respuesta lleva member_id, email_marketing_opt_out y email_marketing_opted_out_at; pedirlo de nuevo para un miembro ya dado de baja no cambia nada. El cambio queda en el registro de auditoría de la organización con el nombre de la clave. Un miembro sin dirección de email responde 422.

Una clave no puede volver a suscribir a un miembro: false responde 422 validation_failed. Solo el miembro puede volver a activar el email de la organización, en Melora Connect, y entonces se envía member.resubscribed.

Solicitud de ejemplo

curl -X POST "https://app.meloraconnect.com/api/public/v1/members/8d2c6f0e-3f59-4a53-9c0e-0f6f5b3a1b21/email-preferences" \
  -H "Authorization: Bearer $MELORA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email_marketing_opt_out":true}'

Respuesta de ejemplo, HTTP 200

{
  "data": {
    "member_id": "8d2c6f0e-3f59-4a53-9c0e-0f6f5b3a1b21",
    "email_marketing_opt_out": true,
    "email_marketing_opted_out_at": "2026-11-05T09:12:44.120Z"
  }
}

GET /api/public/v1/events

Listar eventos por hora de inicio.

Permiso requerido: events.read

Parámetros

  • status (opcional): draft, published, cancelled, completed o archived.
  • starts_after (opcional): una fecha y hora con zona horaria. Solo los eventos que empiezan en ese momento o después.
  • updated_since (opcional): solo los eventos cambiados en ese momento o después.
  • page y per_page (opcionales): vea Listas y formatos.

Cada evento tiene los campos de abajo. Los precios están en centavos.

Campos: id, title, description, event_type, status, starts_at, ends_at, timezone, venue, address, is_virtual, capacity, ticket_price_cents, member_price_cents, highlights, slug, published_at, created_at, updated_at, tags.

Solicitud de ejemplo

curl "https://app.meloraconnect.com/api/public/v1/events?starts_after=2026-11-01T00:00:00Z&per_page=20" \
  -H "Authorization: Bearer $MELORA_API_KEY"

Respuesta de ejemplo, HTTP 200

{
  "data": [
    {
      "id": "5e0c1d8a-9b2f-4c1e-8f3a-6a7b8c9d0e1f",
      "title": "Autumn networking breakfast",
      "event_type": "networking",
      "status": "published",
      "starts_at": "2026-11-12T13:00:00+00:00",
      "ends_at": "2026-11-12T14:30:00+00:00",
      "timezone": "America/New_York",
      "venue": "Harbor Hall",
      "is_virtual": false,
      "capacity": 80,
      "ticket_price_cents": 2500,
      "member_price_cents": 1500,
      "published_at": "2026-10-01T15:00:00+00:00"
    }
  ],
  "page": 1,
  "per_page": 20,
  "has_more": false
}

GET /api/public/v1/events/{id}

Un evento con sus inscripciones.

Permiso requerido: events.read

Parámetros

  • id (en la ruta): el id del evento.

Los campos del evento, más host_committee_name (el comité que lo organiza, o null) y registrations, cada una con los campos de abajo. En una inscripción, member_id es el registro de miembro de la persona inscrita, o null para un invitado.

Campos: id, status, member_id, guest_name, guest_email, ticket_tier_id, checked_in_at, created_at.

Solicitud de ejemplo

curl "https://app.meloraconnect.com/api/public/v1/events/5e0c1d8a-9b2f-4c1e-8f3a-6a7b8c9d0e1f" \
  -H "Authorization: Bearer $MELORA_API_KEY"

Respuesta de ejemplo, HTTP 200

{
  "data": {
    "id": "5e0c1d8a-9b2f-4c1e-8f3a-6a7b8c9d0e1f",
    "title": "Autumn networking breakfast",
    "status": "published",
    "starts_at": "2026-11-12T13:00:00+00:00",
    "capacity": 80,
    "registrations": [
      {
        "id": "a1b2c3d4-0000-4000-8000-000000000001",
        "status": "confirmed",
        "member_id": "8d2c6f0e-3f59-4a53-9c0e-0f6f5b3a1b21",
        "guest_name": null,
        "guest_email": null,
        "ticket_tier_id": null,
        "checked_in_at": null,
        "created_at": "2026-10-02T15:20:00+00:00"
      }
    ]
  }
}

POST /api/public/v1/events

Crear un evento en borrador. Responde 201 con el evento.

Permiso requerido: events.manage

Parámetros

  • title (obligatorio): de 2 a 120 caracteres.
  • event_type (obligatorio): el tipo de evento, por ejemplo networking.
  • format (obligatorio): in_person, virtual o hybrid.
  • starts_at (obligatorio) y ends_at (opcional): fechas y horas con zona horaria.
  • timezone (opcional): el nombre de una zona horaria como America/New_York, que es el valor por defecto.
  • ticket_price_cents y member_price_cents (opcionales): precios en centavos, 0 por defecto.
  • capacity (opcional): el número de lugares.
  • También opcionales: description, venue, address, highlights, tags (una lista de palabras) y language (en, es o fr).

El evento se guarda como borrador. El personal lo revisa y lo publica en Melora Connect, y ahí agrega el enlace para unirse a un evento virtual. Si los eventos no forman parte del plan de la organización, la respuesta es 403 plan_required.

Solicitud de ejemplo

curl -X POST "https://app.meloraconnect.com/api/public/v1/events" \
  -H "Authorization: Bearer $MELORA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"Autumn networking breakfast","event_type":"networking","format":"in_person","starts_at":"2026-11-12T08:00:00-05:00","ends_at":"2026-11-12T09:30:00-05:00","timezone":"America/New_York","venue":"Harbor Hall","capacity":80,"ticket_price_cents":2500,"member_price_cents":1500}'

Respuesta de ejemplo, HTTP 201

{
  "data": {
    "id": "5e0c1d8a-9b2f-4c1e-8f3a-6a7b8c9d0e1f",
    "title": "Autumn networking breakfast",
    "event_type": "networking",
    "status": "draft",
    "starts_at": "2026-11-12T13:00:00+00:00",
    "ends_at": "2026-11-12T14:30:00+00:00",
    "timezone": "America/New_York",
    "venue": "Harbor Hall",
    "is_virtual": false,
    "capacity": 80,
    "ticket_price_cents": 2500,
    "member_price_cents": 1500,
    "published_at": null
  }
}

GET /api/public/v1/dues-invoices

Listar facturas de cuotas, de la más antigua a la más reciente.

Permiso requerido: members.billing.read

Parámetros

  • status (opcional): open, paid, past_due, void, refunded o failed.
  • member_id (opcional): solo las facturas de este miembro.
  • updated_since (opcional): solo las facturas cambiadas en ese momento o después.
  • page y per_page (opcionales): vea Listas y formatos.

Cada factura tiene los campos de abajo. Los importes están en centavos. Las facturas son de solo lectura: los pagos se hacen en Melora Connect.

Campos: id, invoice_number, member_id, dues_subscription_id, status, amount_cents, subtotal_cents, discount_cents, discount_code, currency, period_start, period_end, due_at, paid_at, paid_via, voided_at, void_reason, replaces_invoice_id, created_at, updated_at.

Solicitud de ejemplo

curl "https://app.meloraconnect.com/api/public/v1/dues-invoices?status=paid&updated_since=2026-01-01T00:00:00Z" \
  -H "Authorization: Bearer $MELORA_API_KEY"

Respuesta de ejemplo, HTTP 200

{
  "data": [
    {
      "id": "c4a1e7b2-6d3f-4e8a-9b1c-2d3e4f5a6b7c",
      "invoice_number": "INV-2026-0142",
      "member_id": "8d2c6f0e-3f59-4a53-9c0e-0f6f5b3a1b21",
      "dues_subscription_id": "f1e2d3c4-b5a6-4978-8a9b-0c1d2e3f4a5b",
      "status": "paid",
      "amount_cents": 25000,
      "subtotal_cents": 25000,
      "discount_cents": 0,
      "discount_code": null,
      "currency": "USD",
      "period_start": "2026-03-02",
      "period_end": "2027-03-01",
      "due_at": "2026-03-02T00:00:00+00:00",
      "paid_at": "2026-02-27T16:40:12+00:00",
      "paid_via": "stripe",
      "voided_at": null,
      "void_reason": null,
      "replaces_invoice_id": null,
      "created_at": "2026-02-01T09:00:00+00:00",
      "updated_at": "2026-02-27T16:40:12+00:00"
    }
  ],
  "page": 1,
  "per_page": 50,
  "has_more": false
}

POST /api/public/v1/webhooks

Suscribir una URL de webhook a eventos. Es lo que usa Zapier.

Permiso requerido: settings.manage

Parámetros

  • url (obligatorio): una dirección https que pasa las verificaciones del endpoint.
  • events (obligatorio): una lista de uno o más eventos de webhook.
  • include_contact_details (opcional): true para enviar los datos de contacto de los miembros. La clave necesita entonces también members.read.

Una URL nueva responde 201. Suscribir de nuevo la misma URL reemplaza sus eventos y responde 200. Cada URL cuenta para los 10 endpoints que puede tener una organización; pasado ese número, la respuesta es 403 limit_reached.

Una URL que el personal ya agregó en la pestaña Webhooks responde 409: elimínela allí primero. Si los webhooks no forman parte del plan de la organización, la respuesta es 403 plan_required.

La respuesta incluye id, url, events e include_contact_details del endpoint, pero no un secreto de firma. El endpoint aparece en la pestaña Webhooks como agregado por la API, donde el personal puede emitir un secreto nuevo, que se muestra una vez, para un receptor que verifica las firmas.

Solicitud de ejemplo

curl -X POST "https://app.meloraconnect.com/api/public/v1/webhooks" \
  -H "Authorization: Bearer $MELORA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://hooks.example.com/melora/members","events":["member.created","member.status_changed"]}'

Respuesta de ejemplo, HTTP 201

{
  "data": {
    "id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
    "url": "https://hooks.example.com/melora/members",
    "events": [
      "member.created",
      "member.status_changed"
    ],
    "include_contact_details": false
  }
}

DELETE /api/public/v1/webhooks/{id}

Cancelar la suscripción de un webhook suscrito por la API.

Permiso requerido: settings.manage

Parámetros

  • id (en la ruta): el id que devolvió la suscripción.

Responde 204 sin cuerpo, y los envíos a esa URL se detienen. Un endpoint que el personal agregó en la pestaña Webhooks, o uno de otra organización, responde 404: una clave nunca elimina un endpoint que configuró el personal.

Solicitud de ejemplo

curl -X DELETE "https://app.meloraconnect.com/api/public/v1/webhooks/2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e" \
  -H "Authorization: Bearer $MELORA_API_KEY"

Respuesta de ejemplo, HTTP 204

Sin cuerpo.

Errores

Cada error es JSON con un código que no cambia, un mensaje para personas y a veces details. Decida según el código, no según el mensaje.

HTTP/1.1 403 Forbidden
Content-Type: application/json; charset=utf-8

{
  "error": {
    "code": "permission_denied",
    "message": "This API key does not have the members.write permission.",
    "details": { "required_permission": "members.write" }
  }
}
Estado HTTPCódigo de errorSignificado
401invalid_api_keySin clave, una clave con forma incorrecta o una clave que Melora Connect no conoce. Envíe la clave después de Bearer en el encabezado Authorization.
401api_key_revokedLa clave fue revocada. Cree una nueva.
401api_key_expiredLa clave pasó su fecha de vencimiento. Cree una nueva.
403plan_requiredEl plan no incluye la API (o la función que necesita la solicitud), así que la solicitud se rechaza.
403permission_deniedLa clave no tiene el permiso que necesita esta solicitud. details.required_permission lo nombra.
403billing_holdLa cuenta de Melora Connect está en espera por una factura impaga, lo que pausa este tipo de solicitud.
403account_restrictedLa cuenta está restringida, así que no se puede crear nada nuevo.
403limit_reachedSe superaría un límite del plan, por ejemplo el de miembros activos.
404not_foundNo existe ese registro aquí. Los registros de otras organizaciones nunca se muestran.
422validation_failedEl cuerpo de la solicitud o un parámetro de consulta no es válido. details enumera cada problema.
409conflictEl registro entra en conflicto con uno que ya existe.
413payload_too_largeEl cuerpo de la solicitud supera los 64 KB. Envíe menos campos o divida el trabajo.
429rate_limitedDemasiadas solicitudes. Espere los segundos que indica el encabezado Retry-After.
500internal_errorAlgo falló del lado de Melora Connect. Intente la solicitud de nuevo.

Ejemplos de código

Node.js

Node.js 18 o posterior: leer todos los miembros activos, una página a la vez, y esperar cuando se alcanza el límite.

// Node.js 18 or later: read every active member, a page at a time.
const base = "https://app.meloraconnect.com/api/public/v1";
const headers = { Authorization: `Bearer ${process.env.MELORA_API_KEY}` };

async function allActiveMembers() {
  const members = [];
  for (let page = 1; ; page++) {
    const res = await fetch(`${base}/members?status=active&per_page=100&page=${page}`, { headers });
    if (res.status === 429) {
      await new Promise((r) => setTimeout(r, Number(res.headers.get("retry-after") ?? 60) * 1000));
      page--;
      continue;
    }
    const body = await res.json();
    if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
    members.push(...body.data);
    if (!body.has_more) return members;
  }
}

Python

Python 3 con requests: agregar un miembro, o encontrar el que ya tiene ese correo.

# Python 3 with requests: add a member, or find the one that already has the email.
import os, requests

base = "https://app.meloraconnect.com/api/public/v1"
headers = {"Authorization": f"Bearer {os.environ['MELORA_API_KEY']}"}

res = requests.post(f"{base}/members", headers=headers, json={
    "first_name": "Ana", "last_name": "Ruiz", "email": "ana@example.org",
})
if res.status_code == 409:
    member_id = res.json()["error"]["details"]["existing_member_id"]
else:
    res.raise_for_status()
    member_id = res.json()["data"]["id"]

Buenas prácticas

  • Dé a cada clave solo los permisos que necesita su sistema.
  • Guarde las claves en su servidor. Revoque una clave de inmediato si pudo haberse filtrado.
  • Cada cambio hecho con una clave aparece en el registro de auditoría de la organización con el nombre de la clave.
  • Para enterarse de los cambios en el momento en que ocurren, en lugar de preguntar una y otra vez, use los webhooks.

Véalo con sus propios datos

¿Listo para darles a sus miembros la plataforma que merecen?

Una demostración guiada con nuestro equipo, adaptada a cómo trabaja hoy su organización. En marcha desde 5 semanas después de la firma, con un especialista de Melora a cargo de la configuración.

Reserve una demoCalcule su fecha de puesta en marcha