API
One inbound endpoint so any tool can log work, and outbound notifications so the finished log reaches wherever the team already looks.
API keys
Create a key under Integrations → Push anything in. It is shown once. Only a SHA-256 hash is stored, so a lost key cannot be recovered — revoke it and create another. Keys are prefixed dvl_ so a leaked one is recognisable in a log or a secret scanner.
A key acts as the user who created it. Work pushed in with it lands on that user's days and, if they are in a workspace, in that workspace's report like anything else they logged.
POST /api/ingest
Send activities for one or more days. Each becomes an entry in the same table the in-app logger writes.
curl -X POST https://devlog.app/api/ingest \
-H "Authorization: Bearer dvl_…" \
-H "Content-Type: application/json" \
-d '{
"source": "pagerduty",
"activities": [{
"date": "2026-09-22",
"kind": "support",
"title": "Paged for the checkout outage",
"detail": "Rolled back the pricing deploy, wrote the incident note.",
"hours": 2.5,
"externalId": "pd-incident-8812"
}]
}'| Field | Type | Notes |
|---|---|---|
date | YYYY-MM-DD | Required. The day the work belongs to, in the user's timezone. |
kind | enum | meeting · review · support · planning · research · other. Defaults to other. |
title | string ≤ 300 | Required. |
detail | string ≤ 2000 | Optional. Goes to the model with the day. |
hours | number 0–24 | Optional. Counted as typed hours. |
externalId | string ≤ 200 | Optional but recommended: makes the POST idempotent per (key, source, id). |
source | string ≤ 60 | Optional label shown in the app. Defaults to the key's name. |
{ "ok": true, "accepted": 1, "idempotent": 1 }Up to 100 activities per request. Rows with an externalId are upserted, so a job that retries updates instead of logging the same incident three times; rows without one are inserted. Validation errors come back as 400 with the field path for each issue. Requests are rate limited per key. GET /api/ingest returns this contract as JSON for anyone who opens the URL.
Outbound notifications
Under Integrations, paste an incoming-webhook URL for Slack, Discord or Microsoft Teams, or any https endpoint as a custom webhook. After each successful run the finished log for that day is posted there. The body shape is chosen from the URL's host, so there is nothing to configure beyond pasting it, and a Send test button posts a sample before you rely on it.
Slack and Discord URLs are checked against their known hosts so a typo becomes an error rather than a silently dead notification. Teams and custom endpoints only have to be https.
Other destinations
Beyond Devlog's own database, each day can be mirrored as one row into a Google Sheet (with a column mapping you choose), into your own SQL Server, or into a Notion database. These are configured under Database and Integrations respectively and need no code.