Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .github/workflows/docs-checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Documentation checks

on:
pull_request:
push:
branches: [main]

permissions:
contents: read

jobs:
docs-checks:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Check documentation structure and local links
run: node scripts/check-docs.mjs
- name: Check public OAuth contract
run: node scripts/check-public-contract.mjs
20 changes: 20 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Contributing

Thank you for improving the Memoket API documentation.

Before opening a pull request:

1. Run `node scripts/check-docs.mjs` and, when network access is available,
`node scripts/check-public-contract.mjs`.
2. Confirm behavior against the current public service and the release
implementation—not only an unreleased development branch.
3. Keep examples executable with synthetic values. Never commit access tokens,
webhook secrets, personal recording content, or production identifiers.
4. Document field presence, pagination, idempotency, and error behavior
explicitly when they affect integration safety.
5. Check local images and Markdown links, then preview the README on GitHub.
6. Explain the contract evidence and any release/development difference in the
pull request description.

For a vulnerability or sensitive data exposure, follow [SECURITY.md](SECURITY.md)
instead of opening a public issue.
282 changes: 232 additions & 50 deletions README.md

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Security Policy

The Memoket API handles credentials and recording-derived data. Please do not
open a public GitHub issue for a suspected vulnerability, access token, webhook
secret, raw payload, transcript, or other personal data.

Report security concerns through the contact channel published in the
[Memoket Trust Center](https://trust.memoket.ai/). Include a concise impact
summary, affected endpoint, reproduction steps, and any relevant request IDs.
Use synthetic data and redact credentials and recording content.

Documentation errors that do not expose sensitive information can be reported
through [GitHub Issues](https://github.com/memoket/api-docs/issues).
43 changes: 43 additions & 0 deletions assets/api-flow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/memoket-api-banner.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions assets/memoket-website-badge-navy.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions assets/string-a.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions assets/string-b.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 44 additions & 0 deletions scripts/check-docs.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/usr/bin/env node

import { promises as fs } from "node:fs";
import path from "node:path";
import process from "node:process";

const root = process.cwd();
const files = ["README.md", "CONTRIBUTING.md", "SECURITY.md"];
const errors = [];

for (const file of files) {
const content = await fs.readFile(path.join(root, file), "utf8");
const fences = content.match(/^```/gm)?.length ?? 0;
if (fences % 2 !== 0) errors.push(`${file}: unbalanced fenced code blocks`);

const links = /!?\[[^\]]*\]\(([^)]+)\)|<img[^>]+src="([^"]+)"/g;
for (const match of content.matchAll(links)) {
const raw = (match[1] || match[2]).trim().replace(/^<|>$/g, "");
const target = raw.split("#")[0];
if (!target || /^(https?:|mailto:)/.test(target)) continue;
const resolved = path.resolve(root, path.dirname(file), decodeURIComponent(target));
try {
await fs.access(resolved);
} catch {
errors.push(`${file}: missing local target ${target}`);
}
}
}

const readme = await fs.readFile(path.join(root, "README.md"), "utf8");
for (const required of [
"https://api.memoket.ai",
"summary.completed",
"X-Memoket-Signature",
"SECURITY.md",
]) {
if (!readme.includes(required)) errors.push(`README.md: missing required contract text ${required}`);
}

if (errors.length) {
for (const error of errors) console.error(`- ${error}`);
process.exit(1);
}
console.log("Documentation structure and local links passed.");
32 changes: 32 additions & 0 deletions scripts/check-public-contract.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/env node

import process from "node:process";

const url = "https://api.memoket.ai/.well-known/oauth-authorization-server";
const response = await fetch(url, { headers: { Accept: "application/json" } });
if (!response.ok) {
console.error(`Public contract returned HTTP ${response.status}`);
process.exit(1);
}
const metadata = await response.json();
const expected = {
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",
};
for (const [field, value] of Object.entries(expected)) {
if (metadata[field] !== value) {
console.error(`${field} changed: expected ${value}, received ${metadata[field]}`);
process.exit(1);
}
}
if (!metadata.scopes_supported?.includes("mcp:connect")) {
console.error("mcp:connect is missing from scopes_supported");
process.exit(1);
}
if (!metadata.code_challenge_methods_supported?.includes("S256")) {
console.error("S256 is missing from code_challenge_methods_supported");
process.exit(1);
}
console.log("Public OAuth contract passed.");
Loading