API para investigadores
Automatiza estudios con la API de Populiva: crea y lanza estudios, revisa y bonifica envíos, gestiona grupos, escribe a participantes y recibe webhooks firmados cuando pasan cosas. Crea un token desde la página Desarrolladores de tu laboratorio.
Especificación OpenAPI 3.1 (JSON)
Autenticación
Envía el token de tu laboratorio como token Bearer. Los tokens tienen alcances: read (cada GET), studies (crear y gestionar estudios, revisar envíos, grupos y mensajes) y money (bonos y facturas). Cada token puede hacer 600 solicitudes por minuto. Los participantes aparecen solo como PARTICIPANT_ID de tu laboratorio, y los importes son dólares de EE. UU. como texto.
curl https://populiva.com/api/v1/studies \
-H "Authorization: Bearer pv_..."
curl -X POST https://populiva.com/api/v1/submissions/123/approve \
-H "Authorization: Bearer pv_..."
Endpoints
| Método | Ruta | Qué hace |
|---|---|---|
| get | /api/v1/studies | List your lab's studies (newest first |
| post | /api/v1/studies | Create a draft study (title, description, language, external_url, estimated_minutes, max_minutes, reward, places, screeners, ...) |
| get | /api/v1/studies/{id} | A study |
| patch | /api/v1/studies/{id} | Update a draft study |
| post | /api/v1/studies/{id}/launch | Launch a draft (reserves its cost from your balance) |
| post | /api/v1/studies/{id}/pause | Pause a running study |
| post | /api/v1/studies/{id}/resume | Resume a paused study |
| post | /api/v1/studies/{id}/close | Close a study (releases unused reserve) |
| post | /api/v1/studies/{id}/add_places | Add places to a running study (count) |
| get | /api/v1/studies/{study_id}/submissions | A study's submissions (optional status filter) |
| get | /api/v1/studies/{study_id}/provenance_reports | A study's provenance reports |
| post | /api/v1/studies/{study_id}/provenance_reports | Issue a new provenance report version |
| get | /api/v1/submissions/{id} | A submission |
| post | /api/v1/submissions/{id}/approve | Approve a submission awaiting review |
| post | /api/v1/submissions/{id}/reject | Reject with a reason (no_completion, failed_attention_checks, did_not_follow_instructions, low_effort, duplicate_or_fraud) |
| post | /api/v1/submissions/{id}/bonus | Bonus an approved submission (amount, up to 100.00; money scope) |
| get | /api/v1/groups | Your lab's participant groups |
| post | /api/v1/groups | Create a group (name) |
| get | /api/v1/groups/{id} | A group and its PARTICIPANT_IDs |
| post | /api/v1/groups/{id}/members | Add participant_ids, or remove them with remove=true |
| post | /api/v1/messages | Message one participant (submission_id, body) or a study audience (study_id, audience, group_id, body) |
| get | /api/v1/balance | Your lab's available and reserved balance |
| get | /api/v1/invoices | Your lab's invoices |
| post | /api/v1/invoices | Request an invoice (amount, billing_name, billing_email, billing_address, po_number; money scope) |
Webhooks
Lab → Developer → Webhooks. Each delivery is a POST with a JSON body {id, event, created_at, data} and a `Populiva-Signature: t=<unix time>,v1=<hex HMAC-SHA256 of "<t>.<raw body>" with your endpoint secret>` header. Reject deliveries whose signature doesn't match or whose t is more than 5 minutes old. Failed deliveries are retried after 1 minute, 5 minutes, 30 minutes, 2 hours, and 12 hours.
Eventos: study.launched, study.paused, study.resumed, study.closed, submission.created, submission.reviewed.
# Ruby: verify a delivery
timestamp, signature = request.headers["Populiva-Signature"].scan(/(?:t|v1)=([^,]+)/).flatten
expected = OpenSSL::HMAC.hexdigest("SHA256", ENDPOINT_SECRET, "#{timestamp}.#{request.raw_post}")
valid = ActiveSupport::SecurityUtils.secure_compare(expected, signature) && Time.now.to_i - timestamp.to_i < 300