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
| Escenario | Opcion recomendada |
|---|---|
| Banner de cookies | SDK JavaScript (DPOLab.init) |
| Formulario con backend propio | API server-side (este documento) |
| WordPress / Shopify / Wix (sin backend) | SDK JavaScript (renderConsentCheckbox) |
| App mobile | API server-side |
| Integracion CRM / ERP | API 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
| Campo | Tipo | Requerido | Descripcion |
|---|---|---|---|
choices | object | Si | Objeto con los slugs de los propositos y su estado (true/false) |
action | string | No | GIVEN (otorgado), WITHDRAWN (retirado), UPDATED (actualizado). Default: GIVEN |
source | string | No | Identificador del origen. Default: SDK. Recomendado: API |
subjectEmail | string | No | Email del titular. Requerido si la plantilla tiene IDV nivel 1+ |
userRef | string | No | Referencia del usuario (ID interno, username, etc.) |
sessionId | string | No | ID de sesion para correlacionar multiples acciones |
Respuesta exitosa (201)
{
"success": true,
"data": {
"id": "abc123-def456",
"consentString": "5b94ee5497d6568290284756c2f177482fbf2ef222cd0153..."
}
}Errores comunes
| Status | Codigo | Causa |
|---|---|---|
| 400 | IDV_EMAIL_REQUIRED | La plantilla requiere email (IDV nivel 1+) y no se envio subjectEmail |
| 404 | NOT_FOUND | El widgetKey no existe o la plantilla no esta activa |
| 429 | RATE_LIMITED | Demasiadas 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
200con{ deduplicated: true }en vez de201
Rendimiento
- Rate limit: 10 requests por minuto por IP por widget
- Usa
try/catchy 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
consentStringen la respuesta es la evidencia probatoria - Los registros son visibles en CMP → Plantillas → Informe
Ver tambien
- Banner de Consentimiento — SDK JavaScript para cookies
- Checkbox de Consentimiento — SDK JavaScript para formularios
- Centro de Privacidad — Portal publico de gestion de datos