SDK
Integracion Server-Side (API)

Integracion Server-Side (API)

Registra consentimientos desde tu backend sin usar el SDK JavaScript. Ideal para sitios con servidor propio (Next.js, Astro SSR, Express, Django, Laravel, etc.) donde tienes control total del flujo del formulario.

Esta opcion es complementaria al SDK JavaScript. Usa el SDK para el banner de cookies (frontend) y la API para registrar consentimientos de formularios desde el backend.

Cuando usar cada opcion

EscenarioOpcion recomendada
Banner de cookiesSDK JavaScript (DPOLab.init)
Formulario con backend propioAPI server-side (este documento)
WordPress / Shopify / Wix (sin backend)SDK JavaScript (renderConsentCheckbox)
App mobileAPI server-side
Integracion CRM / ERPAPI server-side

Endpoint

POST https://api.dpolab.com/api/v1/public/consent/{widgetKey}/record
Content-Type: application/json
⚠️

Reemplaza {widgetKey} con el Form Key de tu plantilla. Lo encuentras en CMP → Plantillas → tu plantilla → Detalle → Form Key.

Body del request

{
  "choices": { "privacy_policy": true },
  "action": "GIVEN",
  "source": "API",
  "subjectEmail": "[email protected]"
}

Parametros del body

CampoTipoRequeridoDescripcion
choicesobjectSiObjeto con los slugs de los propositos y su estado (true/false)
actionstringNoGIVEN (otorgado), WITHDRAWN (retirado), UPDATED (actualizado). Default: GIVEN
sourcestringNoIdentificador del origen. Default: SDK. Recomendado: API
subjectEmailstringNoEmail del titular. Requerido si la plantilla tiene IDV nivel 1+
userRefstringNoReferencia del usuario (ID interno, username, etc.)
sessionIdstringNoID de sesion para correlacionar multiples acciones

Respuesta exitosa (201)

{
  "success": true,
  "data": {
    "id": "abc123-def456",
    "consentString": "5b94ee5497d6568290284756c2f177482fbf2ef222cd0153..."
  }
}

Errores comunes

StatusCodigoCausa
400IDV_EMAIL_REQUIREDLa plantilla requiere email (IDV nivel 1+) y no se envio subjectEmail
404NOT_FOUNDEl widgetKey no existe o la plantilla no esta activa
429RATE_LIMITEDDemasiadas solicitudes desde la misma IP (max 10/min por widget)

Ejemplo: Node.js / TypeScript

const DPOLAB_API = 'https://api.dpolab.com'
 
async function registerConsent(
  widgetKey: string,
  purposeSlug: string,
  email: string,
  accepted: boolean
) {
  if (!accepted) return // No registrar rechazos — solo registrar aceptaciones
 
  try {
    const res = await fetch(
      `${DPOLAB_API}/api/v1/public/consent/${widgetKey}/record`,
      {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          choices: { [purposeSlug]: true },
          action: 'GIVEN',
          source: 'API',
          subjectEmail: email,
        }),
      }
    )
    const data = await res.json()
    if (!data.success) {
      console.error('DPOLab consent error:', data.error)
    }
  } catch (err) {
    // No bloquear el flujo del formulario si DPOLab no responde
    console.error('DPOLab consent failed:', err)
  }
}
 
// En tu handler de formulario:
async function handleFormSubmit(formData) {
  // 1. Guardar el lead en tu base de datos
  await saveLead(formData)
 
  // 2. Registrar consentimiento de privacidad
  await registerConsent(
    'WIDGET_KEY_PRIVACIDAD',
    'privacy_policy',
    formData.email,
    formData.acceptPrivacy
  )
 
  // 3. Registrar consentimiento de comunicaciones (si acepto)
  await registerConsent(
    'WIDGET_KEY_COMUNICACIONES',
    'comunicaciones',
    formData.email,
    formData.acceptCommunications
  )
}

Ejemplo: Python / Django

import requests
 
DPOLAB_API = 'https://api.dpolab.com'
 
def register_consent(widget_key, purpose_slug, email):
    try:
        response = requests.post(
            f'{DPOLAB_API}/api/v1/public/consent/{widget_key}/record',
            json={
                'choices': {purpose_slug: True},
                'action': 'GIVEN',
                'source': 'API',
                'subjectEmail': email,
            },
            timeout=5,
        )
        return response.json()
    except Exception:
        pass  # No bloquear el flujo
 
# En tu vista de Django:
def contact_view(request):
    # Guardar lead...
    if request.POST.get('accept_privacy'):
        register_consent('WIDGET_KEY', 'privacy_policy', request.POST['email'])

Ejemplo: PHP / WordPress

function dpolab_register_consent($widget_key, $purpose, $email) {
    $url = "https://api.dpolab.com/api/v1/public/consent/{$widget_key}/record";
 
    wp_remote_post($url, array(
        'headers' => array('Content-Type' => 'application/json'),
        'body' => json_encode(array(
            'choices' => array($purpose => true),
            'action' => 'GIVEN',
            'source' => 'API',
            'subjectEmail' => $email,
        )),
        'timeout' => 5,
    ));
}
 
// En tu hook de Contact Form 7:
add_action('wpcf7_mail_sent', function($contact_form) {
    $submission = WPCF7_Submission::get_instance();
    $data = $submission->get_posted_data();
 
    if (!empty($data['accept-privacy'])) {
        dpolab_register_consent('WIDGET_KEY', 'privacy_policy', $data['your-email']);
    }
});

Consideraciones

Seguridad

  • El endpoint es publico (no requiere API key) — diseñado para formularios web
  • El dominio de origen debe estar registrado en DPOLab (solo aplica a requests con header Origin, no a server-to-server)
  • Las llamadas server-to-server no tienen restriccion de origen

Deduplicacion

  • Si la misma IP envia el mismo consentimiento al mismo template dentro de 5 minutos, se descarta silenciosamente
  • Responde 200 con { deduplicated: true } en vez de 201

Rendimiento

  • Rate limit: 10 requests por minuto por IP por widget
  • Usa try/catch y no bloquees el flujo principal del formulario
  • El registro de consentimiento no es critico para la operacion del formulario

Registro inmutable

  • Cada registro genera un hash SHA-256 encadenado con el registro anterior
  • El consentString en la respuesta es la evidencia probatoria
  • Los registros son visibles en CMP → Plantillas → Informe

Ver tambien