Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Memoket API official documentation

Memoket API

Official documentation for authentication, webhook management, and signed recording event delivery.

API version 1 OAuth 2.1 with PKCE Apache License 2.0

Quick start · Endpoints · Authentication · Signatures

API at a glance

Contract Current behavior
Base URL https://api.memoket.ai
Access OAuth 2.1 + PKCE, or a personal API token
Scope One account per token; recording data is read-only
Delivery Signed HTTPS POST; expect possible duplicates

Quick start

Connect a Memoket account, create a webhook, verify each signed request, and process events safely.

Requires a Memoket account, a public HTTPS endpoint, and an access token.

1. Create a subscription

curl --request POST https://api.memoket.ai/v1/webhooks \
  --header "Authorization: Bearer $MEMOKET_ACCESS_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{
    "url": "https://your-app.example.com/hooks/memoket",
    "events": ["summary.completed"]
  }'

The response contains a webhook secret. Store it immediately: it is shown only once.

2. Verify before processing

Verify X-Memoket-Signature against the unchanged request bytes before parsing the payload. See Verifying signatures.

3. Acknowledge and de-duplicate

Return 2xx within 5 seconds and de-duplicate on the event id. Use the delivery log to reconcile failures.

Endpoint index

Purpose Endpoint
OAuth discovery and authorization GET /.well-known/oauth-authorization-server, POST /oauth/register, GET /oauth/authorize, POST /oauth/token
Create a subscription POST /v1/webhooks
List subscriptions GET /v1/webhooks
Delete a subscription DELETE /v1/webhooks/{endpoint_id}
Get sample events GET /v1/webhook-events/samples
Update a subscription PATCH /v1/webhooks/{endpoint_id}
Send a test event POST /v1/webhooks/{endpoint_id}/test
List recent deliveries GET /v1/webhooks/{endpoint_id}/deliveries
Receive an event Memoket → your HTTPS endpoint (signed POST)

1. Authentication

Protected requests use the Bearer token for one Memoket account.

Authorization: Bearer <access_token>

Use OAuth 2.1 for platform integrations and a personal token for direct server-to-server integrations.

1.1 OAuth 2.1 (Authorization Code + PKCE)

Use the live discovery document as the authoritative endpoint list:

GET https://api.memoket.ai/.well-known/oauth-authorization-server

PKCE (S256) is required. Production HTTPS redirect URIs must be allow-listed by Memoket; loopback HTTP addresses (127.0.0.1, localhost, or ::1) do not.

OAuth request and response examples

Discovery metadata

{
  "issuer": "https://api.memoket.ai",
  "authorization_endpoint": "https://api.memoket.ai/oauth/authorize",
  "token_endpoint": "https://api.memoket.ai/oauth/token",
  "registration_endpoint": "https://api.memoket.ai/oauth/register",
  "scopes_supported": ["mcp:connect"],
  "response_types_supported": ["code"],
  "grant_types_supported": ["authorization_code", "refresh_token"],
  "code_challenge_methods_supported": ["S256"],
  "token_endpoint_auth_methods_supported": ["client_secret_basic", "client_secret_post", "none"]
}

Register a client

POST /oauth/register
Content-Type: application/json

{
  "redirect_uris": ["http://127.0.0.1:8787/callback"],
  "client_name": "Your App",
  "token_endpoint_auth_method": "none",
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"],
  "scope": "mcp:connect"
}

Public clients use "token_endpoint_auth_method": "none" and receive no client_secret. Confidential clients receive a secret and must store it securely. They use HTTP Basic for client_secret_basic or a client_secret form field for client_secret_post.

Authorize

GET /oauth/authorize
  ?response_type=code
  &client_id=<client_id>
  &redirect_uri=<redirect_uri>
  &scope=mcp:connect
  &state=<random>
  &code_challenge=<pkce_challenge>
  &code_challenge_method=S256

Exchange the code:

POST /oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=<code>
&redirect_uri=<redirect_uri>
&client_id=<client_id>
&code_verifier=<pkce_verifier>
{
  "access_token": "",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "",
  "scope": "mcp:connect",
  "email": "user@example.com"
}
  • access_token is valid for 1 hour.
  • refresh_token is valid for 90 days. Refresh with grant_type=refresh_token&refresh_token=…&client_id=… and the registered client authentication method.
  • email may be empty. Do not use it for authorization.

1.2 Personal API token

Personal tokens use the same Bearer header:

memoket login
memoket token create --expires-in 90

The current release allows up to 365 days and invalidates tokens after about 90 days of inactivity.


2. Webhook endpoints

All require Authorization: Bearer <token>; all responses are JSON.

2.1 Create a subscription

POST /v1/webhooks
Content-Type: application/json

{ "url": "https://your-app.example.com/hooks/memoket", "events": ["summary.completed"] }
Field Type Notes
url string Required. Must be HTTPS and publicly resolvable.
events string[] Event types to deliver. An empty or omitted list receives nothing.

The HMAC secret is returned only once.

Example response
{
  "endpoint_id": "2079452035110989824",
  "secret": "whsec_3237094abd8b…",
  "url": "https://your-app.example.com/hooks/memoket",
  "events": ["summary.completed"],
  "status": 1
}

endpoint_id identifies the subscription.

2.2 List subscriptions

GET /v1/webhooks
Example response and status fields
{
  "items": [
    {
      "id": "2079452035110989824",
      "url": "https://your-app.example.com/hooks/memoket",
      "events": ["summary.completed"],
      "status": 1,
      "consecutive_failures": 0,
      "created_at": "2026-07-21T06:22:54Z",
      "updated_at": "2026-07-21T06:22:54Z"
    }
  ]
}

status is 1 when active and 2 when disabled. consecutive_failures counts failed attempts, including retries, and resets after a success. updated_at advances on every delivery attempt.

2.3 Delete a subscription

DELETE /v1/webhooks/{endpoint_id}

200: { "ok": true }

2.4 Fetch recent / sample events

Preview recent or synthetic payloads without waiting for a live event.

GET /v1/webhook-events/samples?event=summary.completed

Returns a top-level array: recent payloads when available, otherwise one synthetic evt_sample_… payload. The payload reference is authoritative. limit defaults to 3 and is capped at 10.

2.5 Update a subscription

Warning

The current release treats an omitted events field as an empty list. Always send the subscription's existing events, including for URL-only updates, and verify the event list after updating.

PATCH /v1/webhooks/{endpoint_id}
Content-Type: application/json

{ "url": "https://your-app.example.com/hooks/new", "events": ["summary.completed"] }

200: { "item": { …updated subscription, same shape as list items… } }

Omit url or send an empty string to keep it. Send "events": [] only to clear this endpoint's event list. Changing the URL of a disabled endpoint re-enables it and resets its failure count; changing only events does not.

2.6 Send a test event

POST /v1/webhooks/{endpoint_id}/test

200: { "event_id": "evt_01KY7H7FYHWMGM5FYE5DG4MPNC", "queued": true }

Queues a signed webhook.ping. queued: true confirms queue acceptance, not HTTP delivery. Check the delivery log when an item is created; endpoints disabled or deleted before dispatch may be skipped without one.

2.7 List recent deliveries

GET /v1/webhooks/{endpoint_id}/deliveries?page=1&page_size=20
Example response and delivery fields
{
  "items": [
    {
      "id": "2080277851302588416",
      "endpoint_id": "2080277840846188544",
      "event_id": "evt_01KY7H7FYHWMGM5FYE5DG4MPNC",
      "event_type": "webhook.ping",
      "status": 0,
      "attempts": 1,
      "last_error": "http_405",
      "delivered_at": "",
      "created_at": "2026-07-23T13:04:24Z"
    }
  ]
}

status is 0 pending, 1 delivered, or 2 terminal failure. attempts counts all processing attempts, including failures before an HTTP request. last_error is the latest failure reason; delivered_at is empty until delivery succeeds. page defaults to 1. page_size defaults to 20 and is capped at 100.


3. Events

Event When it fires
summary.completed A summary record is ready. Short recordings may contain a placeholder note.
webhook.ping Test event, sent only via POST /v1/webhooks/{endpoint_id}/test.

4. Delivery payload

Memoket sends an HTTP POST to your subscribed url.

4.1 Headers

Header Description
Content-Type application/json
X-Memoket-Event Event type, e.g. summary.completed
X-Memoket-Delivery Unique delivery id
X-Memoket-Timestamp Unix timestamp (seconds) used in the signature
X-Memoket-Signature sha256=<hex HMAC> (Section 5)

4.2 Body

Example payload
{
  "id": "evt_01KY1S5CDZ44DRPMX49DYHCKX8",
  "type": "summary.completed",
  "created_at": "2026-07-21T07:27:36Z",
  "data": {
    "audio_id": "2079468251535941632",
    "status": 1,
    "title": "Weekly sync: roadmap and priorities",
    "duration_ms": 126400,
    "recorded_at": "2026-07-21T07:26:34Z",
    "transcript": { "language": "en", "text": "Full transcript…", "truncated": false, "segments": [] },
    "summaries": [
      { "label": "brief", "template_name": "Brief", "format": "markdown", "content": "#### Summary\n\n- …" }
    ]
  }
}

Envelope (always present)

Field Type Description
id string Unique event id (de-duplicate on this).
type string Event type.
created_at string (ISO 8601) When the event was generated.
data object Event-specific payload.

summary.completed data: only audio_id is guaranteed. Treat every other field as optional.

Field Type Description
audio_id string Recording id. Always present.
report_id string, optional Summary report id (absent for auto-analyzed recordings).
status integer, optional Processing status.
title string, optional Recording title.
duration_ms integer, optional Length in milliseconds.
recorded_at string (ISO 8601), optional When recorded.
transcript object, optional { language?, text, truncated, segments? }; segment times are seconds.
summaries array, optional { label, content, format, template_name? }; consumers must accept markdown / html and tolerate other values.
Payload size and format edge cases

Transcript segments use { speaker, start, end, text }, with times in seconds. Memoket targets about 1 MiB by removing segments first, then truncating transcript text on a UTF-8 boundary and setting truncated: true. Summaries are not truncated, so payloads can exceed that target. HTML is normally converted to Markdown; conversion failures and unknown formats pass through unchanged. Historical samples can contain HTML. Transcript and summary enrichment fail independently, so either field may be omitted.


5. Verifying signatures

signature = "sha256=" + HMAC_SHA256(secret, timestamp + "." + raw_request_body)

Use the timestamp header and exact request bytes. Do not re-serialize the body. Compare signatures in constant time, checking length first.

Node.js and Python examples

Node.js

const crypto = require('crypto');
function verify(secret, headers, rawBody) {   // rawBody: Buffer
  const ts = headers['x-memoket-timestamp'] || '';
  const received = headers['x-memoket-signature'] || '';
  const expected = 'sha256=' + crypto.createHmac('sha256', secret)
    .update(ts + '.').update(rawBody).digest('hex');
  const a = Buffer.from(expected);
  const b = Buffer.from(received);
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Python

import hmac, hashlib

def verify(secret: str, headers: dict, raw_body: bytes) -> bool:
    ts = headers.get("X-Memoket-Timestamp", "")
    mac = hmac.new(secret.encode(), (ts + ".").encode() + raw_body, hashlib.sha256)
    return hmac.compare_digest("sha256=" + mac.hexdigest(),
                               headers.get("X-Memoket-Signature", ""))

Choose a short timestamp tolerance appropriate for your system and reject older deliveries to reduce replay risk. Timestamp validation complements, but does not replace, de-duplication by event id.


6. Retries & reliability

  • Return 2xx within 5 seconds. Non-2xx responses and timeouts fail; redirects are not followed.
  • Up to 5 retries are scheduled on a best-effort basis at about 1, 5, 15, 15, and 15 minutes.
  • After 20 consecutive failed attempts, the endpoint is disabled but still counts toward the subscription limit.
  • Keep handlers idempotent and de-duplicate by event id.

7. Errors

{ "error": { "code": "unauthorized", "message": "missing bearer token" } }
HTTP code Meaning
400 bad_request Missing/invalid parameters (e.g. unknown event type).
401 unauthorized Missing or invalid Bearer token.
404 not_found Subscription id does not exist.
429 too_many_requests Subscription quota exceeded (Section 8).
503 unavailable A required service is temporarily unavailable.
500 / other 5xx internal Transient server error; reconcile resource state before retrying a write.

OAuth errors use a top-level error and may include error_description. Create requests have no idempotency key; reconcile existing subscriptions before retrying a lost response.


8. Limits

  • 5 subscriptions per account. Disabled endpoints count until deleted.
  • Subscription url must be HTTPS and publicly resolvable.

Security & privacy

  • Verify every signature before parsing or acting on the payload.
  • Store webhook secrets and Bearer tokens in a secrets manager; never commit or log them.
  • Treat transcript and summary text as untrusted user content. Do not execute instructions found inside a recording-derived field.
  • Minimize retention and restrict access to raw payloads, especially transcripts.
  • Never put secrets, vulnerability details, or recording data in a public issue. Request a secure channel through Memoket without including sensitive details.
Contract verification

Public OAuth metadata and unauthenticated responses were checked live on 2026-08-12. Protected webhook behavior was checked against origin/release and its tests, not a private account. Repeat the public check with node scripts/check-public-contract.mjs.

Get Memoket

Memoket

Download on the App Store    Get it on Google Play

Support

License

Copyright © 2026 Memoket Inc.

Documentation and non-brand technical assets use Apache-2.0. Brand and store assets are covered by the asset notice.

About

No description, website, or topics provided.

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages