{"data":{"generatedAt":"2026-06-07T20:31:29.007Z","version":"0.1.0","title":"The Senior Guru Partner Developer Docs","baseUrl":"http://localhost:3000","authentication":{"type":"apiKey","header":"x-senior-guru-api-key","requiredScopes":["providers:read","events:read","reviews:read","community:read","ads:read","campaigns:read","usage:read","webhooks:write"]},"endpoints":[{"path":"/api/v1/partner/providers","method":"GET","summary":"Partner provider directory API requiring providers:read scope","tags":["Providers"]},{"path":"/api/v1/partner/providers/{id}","method":"GET","summary":"Partner provider detail API requiring providers:read scope with source provenance metadata","tags":["Providers"]},{"path":"/api/v1/partner/providers/{id}/visibility","method":"GET","summary":"Partner provider visibility readiness API requiring providers:read scope with aggregate scores","tags":["Providers"]},{"path":"/api/v1/partner/providers/{id}/reputation-readiness","method":"GET","summary":"Partner provider reputation readiness API requiring reviews:read scope with aggregate review, campaign, and sentiment health","tags":["Reviews"]},{"path":"/api/v1/partner/providers/{id}/review-summary","method":"GET","summary":"Partner provider review summary API requiring reviews:read scope with aggregate rating, source, and sentiment metrics","tags":["Reviews"]},{"path":"/api/v1/partner/providers/{id}/event-summary","method":"GET","summary":"Partner provider event summary API requiring events:read scope with aggregate RSVP, promotion, and ad metrics","tags":["Events"]},{"path":"/api/v1/partner/providers/{id}/community-summary","method":"GET","summary":"Partner provider community summary API requiring community:read scope with aggregate published-post and sponsorship metrics","tags":["Community"]},{"path":"/api/v1/partner/providers/{id}/ad-summary","method":"GET","summary":"Partner provider ad summary API requiring ads:read scope with aggregate delivery, placement, and health metrics","tags":["Ads"]},{"path":"/api/v1/partner/providers/{id}/campaign-summary","method":"GET","summary":"Partner provider campaign summary API requiring campaigns:read scope with aggregate campaign, asset, and metric rollups","tags":["Campaigns"]},{"path":"/api/v1/partner/providers/{id}/newsletter-summary","method":"GET","summary":"Partner provider newsletter summary API requiring newsroom:read scope with aggregate delivery and performance metrics","tags":["Newsroom"]},{"path":"/api/v1/partner/events","method":"GET","summary":"Partner events API requiring events:read scope","tags":["Events"]},{"path":"/api/v1/partner/events/{id}/analytics","method":"GET","summary":"Partner event analytics API requiring events:read scope with aggregate RSVP and promotion metrics","tags":["Events"]},{"path":"/api/v1/partner/reviews","method":"GET","summary":"Partner published reviews API requiring reviews:read scope with privacy-safe reviewer fields","tags":["Reviews"]},{"path":"/api/v1/partner/community/posts","method":"GET","summary":"Partner published community posts API requiring community:read scope with pagination and sponsorship disclosures","tags":["Community"]},{"path":"/api/v1/partner/newsroom/articles","method":"GET","summary":"Partner published newsroom articles API requiring newsroom:read scope with attribution and preview-only body metadata","tags":["Newsroom"]},{"path":"/api/v1/partner/newsroom/newsletters","method":"GET","summary":"Partner public newsletter editions API requiring newsroom:read scope with recipient-safe metadata","tags":["Newsroom"]},{"path":"/api/v1/partner/newsroom/performance","method":"GET","summary":"Partner aggregated newsroom performance API requiring newsroom:read scope without raw metric payloads","tags":["Newsroom"]},{"path":"/api/v1/partner/newsroom/readiness","method":"GET","summary":"Partner newsroom syndication readiness API requiring newsroom:read scope with aggregate blocker evidence","tags":["Newsroom"]},{"path":"/api/v1/partner/newsroom/sources","method":"GET","summary":"Partner approved newsroom source registry API requiring newsroom:read scope with attribution metadata","tags":["Newsroom"]},{"path":"/api/v1/partner/ads/placements","method":"GET","summary":"Partner ad placement inventory API requiring ads:read scope with disclosure and optional delivery preview metadata","tags":["Ads"]},{"path":"/api/v1/partner/aggregation/readiness","method":"GET","summary":"Partner aggregation readiness API requiring providers:read scope with aggregate source, import, crawler, and quality health","tags":["Aggregation"]},{"path":"/api/v1/partner/campaigns","method":"GET","summary":"Partner published campaigns API requiring campaigns:read scope with optional provider metrics rollup","tags":["Campaigns"]},{"path":"/api/v1/partner/claims","method":"POST","summary":"Partner provider claim/data-correction submission API requiring claims:write scope with verification checklist evidence","tags":["Claims"]},{"path":"/api/v1/partner/claims/{id}","method":"GET","summary":"Partner provider claim status API requiring claims:write scope and matching claimant email","tags":["Claims"]},{"path":"/api/v1/partner/claims/{id}/verification-evidence","method":"POST","summary":"Partner provider claim evidence submission API requiring claims:write scope, claimant email match, and attestation","tags":["Claims"]},{"path":"/api/v1/partner/usage","method":"GET","summary":"Partner-scoped API usage summary, retention policy, or CSV export requiring usage:read scope","tags":["System"]},{"path":"/api/v1/partner/onboarding-checklist","method":"GET","summary":"Return the partner sandbox onboarding checklist with scopes, evidence, and production promotion blockers","tags":["System"]},{"path":"/api/v1/partner/changelog","method":"GET","summary":"Return partner API version changelog, deprecation policy, migration notes, and planned release signals","tags":["System"]},{"path":"/api/v1/partner/sdk-package-plan","method":"GET","summary":"Return webhook SDK package publishing plan, security controls, release gates, and owner blockers","tags":["System"]},{"path":"/api/v1/partner/sandbox-evidence","method":"GET","summary":"Return JSON or CSV partner sandbox evidence bundle for promotion review","tags":["System"]},{"path":"/api/v1/partner/response-envelope","method":"GET","summary":"Return partner response envelope version, headers, paths, and migration rules","tags":["System"]},{"path":"/api/v1/partner/response-pagination","method":"GET","summary":"Return partner response pagination parameters, meta shape, and traversal rules","tags":["System"]},{"path":"/api/v1/partner/pagination-evaluation","method":"GET","summary":"Return JSON or CSV partner cursor pagination evaluation, offset limits, migration gates, and endpoint candidates","tags":["System"]},{"path":"/api/v1/partner/webhooks/signing-guide","method":"GET","summary":"Return webhook signing headers, HMAC verification steps, event list, and deterministic sample payload","tags":["System"]},{"path":"/api/v1/partner/webhooks/verify","method":"POST","summary":"Verify a webhook payload signature for an owned subscription requiring webhooks:write scope","tags":["System"]},{"path":"/api/v1/partner/developer-docs","method":"GET","summary":"Return partner developer documentation, SDK examples, OpenAPI endpoints, and webhook signing contracts","tags":["System"]},{"path":"/api/v1/partner/pagination-volume-evidence","method":"GET","summary":"Return JSON or CSV partner cursor pagination production-volume evidence and threshold blockers","tags":["System"]},{"path":"/api/v1/partner/sdk-publish-readiness","method":"GET","summary":"Return JSON or CSV webhook SDK registry publish readiness, owner approvals, and smoke evidence blockers","tags":["System"]}],"webhooks":{"signatureHeader":"x-senior-guru-signature","eventHeader":"x-senior-guru-event","algorithm":"HMAC-SHA256","signedContent":"timestamp.rawBody","toleranceSeconds":300,"supportedEvents":["provider.claimed","provider.updated","provider.contact.created","review.created","review.response.published","event.created","event.rsvp.created","campaign.published","campaign.metric.updated","ad.impression.recorded","ad.click.recorded","community.post.created"],"sampleSignature":"t=1778792400,v1=c6712f63cdc2c4dc3c0df540b951905799fab2b40a2a0f61570461a0d07166c2","sampleRawBody":"{\"id\":\"webhook-delivery-example\",\"eventType\":\"provider.updated\",\"subjectId\":\"provider-example\",\"payload\":{\"providerId\":\"provider-example\",\"status\":\"updated\"},\"createdAt\":\"2026-05-14T21:00:00.000Z\"}","verificationSteps":["Read the exact raw request body before JSON parsing.","Parse x-senior-guru-signature into t and v1 values.","Reject requests when the timestamp is outside the configured tolerance window.","Compute HMAC-SHA256 with the webhook signing secret over `${t}.${rawBody}`.","Compare the computed v1 digest to the supplied v1 digest using a constant-time comparison.","Use the webhook delivery id as an idempotency key before writing downstream changes."]},"sdkExamples":[{"language":"node","title":"Verify a webhook signature in Node.js","code":"import crypto from \"node:crypto\";\n\nconst secret = \"whsec_example_do_not_use\";\nconst timestamp = \"1778792400\";\nconst rawBody = \"{\\\"id\\\":\\\"webhook-delivery-example\\\",\\\"eventType\\\":\\\"provider.updated\\\",\\\"subjectId\\\":\\\"provider-example\\\",\\\"payload\\\":{\\\"providerId\\\":\\\"provider-example\\\",\\\"status\\\":\\\"updated\\\"},\\\"createdAt\\\":\\\"2026-05-14T21:00:00.000Z\\\"}\";\nconst signature = \"t=1778792400,v1=c6712f63cdc2c4dc3c0df540b951905799fab2b40a2a0f61570461a0d07166c2\";\nconst expectedDigest = crypto\n  .createHmac(\"sha256\", secret)\n  .update(`${timestamp}.${rawBody}`)\n  .digest(\"hex\");\nconst suppliedDigest = signature.split(\"v1=\")[1];\nconst valid = crypto.timingSafeEqual(Buffer.from(expectedDigest), Buffer.from(suppliedDigest));"},{"language":"python","title":"Verify a webhook signature in Python","code":"import hmac\nimport hashlib\n\nsecret = \"whsec_example_do_not_use\"\ntimestamp = \"1778792400\"\nraw_body = \"{\\\"id\\\":\\\"webhook-delivery-example\\\",\\\"eventType\\\":\\\"provider.updated\\\",\\\"subjectId\\\":\\\"provider-example\\\",\\\"payload\\\":{\\\"providerId\\\":\\\"provider-example\\\",\\\"status\\\":\\\"updated\\\"},\\\"createdAt\\\":\\\"2026-05-14T21:00:00.000Z\\\"}\"\nsignature = \"t=1778792400,v1=c6712f63cdc2c4dc3c0df540b951905799fab2b40a2a0f61570461a0d07166c2\"\nexpected_digest = hmac.new(secret.encode(), f\"{timestamp}.{raw_body}\".encode(), hashlib.sha256).hexdigest()\nsupplied_digest = signature.split(\"v1=\")[1]\nvalid = hmac.compare_digest(expected_digest, supplied_digest)"},{"language":"curl","title":"Call the partner providers endpoint","code":"curl -sS \\\n  -H \"x-senior-guru-api-key: $SENIOR_GURU_API_KEY\" \\\n  -H \"accept: application/json\" \\\n  https://theseniorguru.vercel.app/api/v1/partner/providers"}],"sandboxOnboarding":{"generatedAt":"2026-06-07T20:31:29.007Z","title":"Partner Sandbox Onboarding Checklist","mode":"sandbox","objective":"Move a partner from scoped sandbox access to production approval with auditable API usage, webhook verification, and explicit owner review.","minimumScopes":["providers:read","events:read","usage:read"],"optionalScopes":["webhooks:write","reviews:read","community:read","newsroom:read","campaigns:read","ads:read","claims:write"],"promotionControls":["Sandbox clients must keep sandboxMode=true until owner approval is recorded.","Partner keys are secret-once and revocation-first if custody is uncertain.","Webhook subscriptions require HTTPS, approved event types, and raw-body signature verification.","Usage evidence and rate-limit headers must be reviewed before live promotion."],"steps":[{"key":"create-sandbox-client","title":"Create a sandbox API client with least-privilege scopes","owner":"platform_admin","requiredScopes":[],"endpoint":"POST /api/v1/admin/api-clients","completionSignal":"Client has sandboxMode=true, status=active, rate limit, owner type, and approved scopes.","blocker":"Do not issue live-mode clients until partner business owner, data use, and webhook purpose are approved."},{"key":"mint-sandbox-key","title":"Mint one sandbox key and store the secret outside The Senior Guru","owner":"platform_admin","requiredScopes":[],"endpoint":"POST /api/v1/admin/api-clients/{id}/keys","completionSignal":"Key preview is visible in admin records and the full secret was copied once into the partner vault.","blocker":"Lost secrets must be revoked and reissued; backend never exposes stored key material."},{"key":"read-provider-inventory","title":"Call provider inventory from the partner environment","owner":"partner_engineer","requiredScopes":["providers:read"],"endpoint":"GET /api/v1/partner/providers","completionSignal":"Response includes provider records and rate-limit headers with x-senior-guru-sandbox=true.","blocker":"403 responses mean the key is missing providers:read scope or the client is paused/revoked."},{"key":"read-provider-detail","title":"Call provider detail by id or slug with source provenance","owner":"partner_engineer","requiredScopes":["providers:read"],"endpoint":"GET /api/v1/partner/providers/{id}","completionSignal":"Response includes one approved provider record, source provenance, lookup metadata, partner envelope headers, and excludes internal admin notes or claim verification evidence.","blocker":"Do not hydrate partner provider profiles from non-approved statuses or from internal claim verification evidence."},{"key":"read-provider-visibility","title":"Call provider visibility readiness without internal action links","owner":"partner_ops","requiredScopes":["providers:read"],"endpoint":"GET /api/v1/partner/providers/{id}/visibility","completionSignal":"Response includes aggregate provider readiness scores, metrics, missing public profile fields, and next-best-action labels without entitlement keys, internal URLs, or claim evidence.","blocker":"Do not use provider readiness evidence for partner ranking when internal entitlements, audit records, or claim verification evidence are required by the partner workflow."},{"key":"read-provider-reputation-readiness","title":"Call provider reputation readiness without reviewer identity","owner":"partner_ops","requiredScopes":["reviews:read"],"endpoint":"GET /api/v1/partner/providers/{id}/reputation-readiness","completionSignal":"Response includes aggregate review, campaign, sentiment, blocker, and next-action readiness with partner envelope headers and no reviewer emails, request recipients, moderation notes, or internal action URLs.","blocker":"Do not use reputation readiness externally when the partner workflow requires raw reviewer identity, moderation evidence, or recipient-level request records."},{"key":"read-provider-review-summary","title":"Call provider review summary without raw review text","owner":"partner_ops","requiredScopes":["reviews:read"],"endpoint":"GET /api/v1/partner/providers/{id}/review-summary","completionSignal":"Response includes aggregate published-review count, rating distribution, source counts, sentiment totals, partner envelope headers, and no reviewer names, emails, body text, moderation status, or recipient details.","blocker":"Do not use review summary output as a raw testimonial feed; use the published reviews endpoint when approved display attribution is required."},{"key":"read-provider-event-summary","title":"Call provider event summary without attendee PII","owner":"partner_ops","requiredScopes":["events:read"],"endpoint":"GET /api/v1/partner/providers/{id}/event-summary","completionSignal":"Response includes provider-scoped event counts, RSVP totals, promotion totals, ad metrics, public event references, partner envelope headers, and no attendee names, emails, phones, consent payloads, or per-RSVP rows.","blocker":"Do not share provider event performance externally if the partner workflow requires attendee-level consent evidence or raw RSVP records."},{"key":"read-provider-community-summary","title":"Call provider community summary without author identity","owner":"partner_ops","requiredScopes":["community:read"],"endpoint":"GET /api/v1/partner/providers/{id}/community-summary","completionSignal":"Response includes provider-scoped published post counts, sponsorship disclosure totals, post type/location distribution, public post references, partner envelope headers, and no author names, body text, comments, member identity, or moderation status.","blocker":"Do not use community summary output as a raw community feed; use the published community posts endpoint when approved post display rules are required."},{"key":"read-provider-ad-summary","title":"Call provider ad summary without raw creative payloads","owner":"partner_ops","requiredScopes":["ads:read"],"endpoint":"GET /api/v1/partner/providers/{id}/ad-summary","completionSignal":"Response includes provider-scoped aggregate delivery totals, placement rollups, ad health, recommendations, partner envelope headers, and no raw creative payloads, destination URLs, visitor context, request IDs, or row-level impression/click records.","blocker":"Do not use ad summary output for creative rendering; use approved ad placement inventory and preserve disclosure labels before rendering sponsored placements."},{"key":"read-provider-campaign-summary","title":"Call provider campaign summary without raw asset payloads","owner":"partner_ops","requiredScopes":["campaigns:read"],"endpoint":"GET /api/v1/partner/providers/{id}/campaign-summary","completionSignal":"Response includes provider-scoped campaign totals, asset approval totals, metric rollups, type/status/channel distributions, public campaign references, partner envelope headers, and no campaign audience payloads, asset bodies, asset payloads, metric payloads, or row-level metric records.","blocker":"Do not mirror campaign assets or audience rules from summary output; use approved campaign inventory and owner-reviewed channel rules before external display."},{"key":"read-community-events","title":"Call event inventory and confirm date/location handling","owner":"partner_engineer","requiredScopes":["events:read"],"endpoint":"GET /api/v1/partner/events","completionSignal":"Response includes event records with community-safe metadata for sandbox validation.","blocker":"Do not mirror events publicly until partner display rules and sponsorship disclosures are reviewed."},{"key":"read-event-analytics","title":"Call aggregate event analytics without attendee PII","owner":"partner_ops","requiredScopes":["events:read"],"endpoint":"GET /api/v1/partner/events/{id}/analytics","completionSignal":"Response includes aggregate RSVP, promotion, and ad metrics with partner envelope headers and no attendee names, emails, phones, or consent payloads.","blocker":"Do not share event performance externally if attendee PII, consent payloads, or provider-only notes are required by the partner workflow."},{"key":"read-published-reviews","title":"Call published review inventory without reviewer email exposure","owner":"partner_engineer","requiredScopes":["reviews:read"],"endpoint":"GET /api/v1/partner/reviews","completionSignal":"Response includes only published reviews, provider context, pagination metadata, and no reviewer email field.","blocker":"Do not syndicate reviews until partner display rules, attribution, and moderation status handling are approved."},{"key":"read-community-posts","title":"Call published community posts with sponsorship disclosures","owner":"partner_engineer","requiredScopes":["community:read"],"endpoint":"GET /api/v1/partner/community/posts","completionSignal":"Response includes only published community posts, optional location/topic filters, pagination metadata, and disclosure labels for sponsored posts.","blocker":"Do not mirror community content until partner moderation display rules and sponsored-content disclosure handling are approved."},{"key":"read-newsroom-articles","title":"Call published newsroom articles with attribution metadata","owner":"partner_engineer","requiredScopes":["newsroom:read"],"endpoint":"GET /api/v1/partner/newsroom/articles","completionSignal":"Response includes only published articles, preview body text, source links, topic/audience filters, pagination metadata, and partner envelope headers.","blocker":"Do not syndicate editorial content unless attribution, preview-only body display, and partner content-use approval are preserved."},{"key":"read-newsroom-newsletters","title":"Call public newsletter editions without recipient details","owner":"partner_engineer","requiredScopes":["newsroom:read"],"endpoint":"GET /api/v1/partner/newsroom/newsletters","completionSignal":"Response includes approved, scheduled, or sent newsletter metadata, linked article references, pagination metadata, and no recipient or delivery-attempt records.","blocker":"Do not syndicate newsletter editions unless attribution, unsubscribe expectations, and recipient privacy boundaries are preserved."},{"key":"read-provider-newsletter-summary","title":"Call provider newsletter summary without recipient details","owner":"partner_ops","requiredScopes":["newsroom:read"],"endpoint":"GET /api/v1/partner/providers/{id}/newsletter-summary","completionSignal":"Response includes provider-scoped newsletter delivery and performance rollups, blocker evidence, and no recipient identities, delivery payload previews, delivery attempt IDs, audience segments, or raw metric payloads.","blocker":"Do not use provider newsletter analytics unless aggregate-only reporting and recipient privacy boundaries are preserved."},{"key":"read-newsroom-performance","title":"Call aggregated newsroom performance without raw payloads","owner":"partner_ops","requiredScopes":["newsroom:read"],"endpoint":"GET /api/v1/partner/newsroom/performance","completionSignal":"Response includes aggregate totals, channel rollups, top article/newsletter rows, partner envelope metadata, and no raw metric payloads or recipient records.","blocker":"Do not use partner content performance evidence unless aggregation-only reporting and recipient privacy boundaries are preserved."},{"key":"read-newsroom-readiness","title":"Call newsroom syndication readiness before mirroring content","owner":"partner_ops","requiredScopes":["newsroom:read"],"endpoint":"GET /api/v1/partner/newsroom/readiness","completionSignal":"Response includes aggregate source, article, derivative, and blocker summaries with no draft bodies, source item bodies, or admin review notes.","blocker":"Do not enable partner syndication when readiness status is blocked or action_required without partner content-use and editorial approval."},{"key":"read-newsroom-sources","title":"Call approved newsroom source attribution metadata","owner":"partner_engineer","requiredScopes":["newsroom:read"],"endpoint":"GET /api/v1/partner/newsroom/sources","completionSignal":"Response includes only approved source records, attribution notes, pagination metadata, and excludes pending, blocked, legal-review, and raw source item bodies.","blocker":"Do not attribute or mirror newsroom content from sources that are pending, blocked, or awaiting legal review."},{"key":"read-ad-placements","title":"Call ad placement inventory with disclosure metadata","owner":"partner_engineer","requiredScopes":["ads:read"],"endpoint":"GET /api/v1/partner/ads/placements","completionSignal":"Response includes active placements, surfaces, disclosure labels, pagination metadata, and optional delivery preview data when includeCreatives=true.","blocker":"Do not render paid placements unless the partner UI preserves disclosure labels and separates organic ranking from sponsored placement."},{"key":"read-aggregation-readiness","title":"Call aggregation readiness before relying on provider inventory freshness","owner":"partner_ops","requiredScopes":["providers:read"],"endpoint":"GET /api/v1/partner/aggregation/readiness","completionSignal":"Response includes aggregate source, import, crawler, launch target, and quality health with no source IDs, base URLs, terms notes, queue rows, import batches, crawl jobs, or quality flag rows.","blocker":"Do not market inventory freshness or launch coverage claims unless aggregate readiness is ready or action_required blockers are accepted."},{"key":"read-published-campaigns","title":"Call published campaign inventory with optional metrics","owner":"partner_engineer","requiredScopes":["campaigns:read"],"endpoint":"GET /api/v1/partner/campaigns","completionSignal":"Response includes published non-blocked campaigns, provider/type/status filters, pagination metadata, and optional metrics when includeMetrics=true.","blocker":"Do not mirror campaign content until partner campaign purpose, channel rules, consent boundaries, and attribution are approved."},{"key":"submit-provider-claim","title":"Submit a provider claim or data correction request","owner":"partner_engineer","requiredScopes":["claims:write"],"endpoint":"POST /api/v1/partner/claims","completionSignal":"Response includes the created provider claim, verification checklist, next action, partner envelope metadata, and API audit evidence.","blocker":"Do not submit third-party correction claims without claimant authority, provider identity evidence, and partner data-use approval."},{"key":"poll-provider-claim-status","title":"Poll claim status with claimant email verification","owner":"partner_engineer","requiredScopes":["claims:write"],"endpoint":"GET /api/v1/partner/claims/{id}?claimantEmail={email}","completionSignal":"Response includes the claim, checklist, next action, and partner envelope metadata only when the claimant email matches.","blocker":"Do not expose claim status in partner systems unless the claimant email match and partner data-use approval are both preserved."},{"key":"submit-provider-claim-evidence","title":"Submit provider claim verification evidence with claimant match","owner":"partner_engineer","requiredScopes":["claims:write"],"endpoint":"POST /api/v1/partner/claims/{id}/verification-evidence","completionSignal":"Response includes safe verification attempt status and refreshed claim checklist after claimantEmail match and attestation acceptance; raw evidence, attempt IDs, verification targets, and policy decisions are excluded.","blocker":"Do not submit or display claim evidence unless the claimant email matches the original claim and the claimant has accepted the attestation."},{"key":"verify-usage-evidence","title":"Review JSON and CSV usage evidence","owner":"partner_ops","requiredScopes":["usage:read"],"endpoint":"GET /api/v1/partner/usage?format=csv","completionSignal":"Usage export shows allowed, blocked, and rate-limited calls for partner operations review.","blocker":"Missing usage evidence blocks production promotion because launch operations cannot audit partner access."},{"key":"create-webhook-subscription","title":"Register the sandbox webhook endpoint","owner":"platform_admin","requiredScopes":["webhooks:write"],"endpoint":"POST /api/v1/admin/webhook-subscriptions","completionSignal":"Subscription uses HTTPS, approved event types, active status, and a one-time signing secret.","blocker":"HTTP targets, unsupported events, and missing signing-secret custody block subscription approval."},{"key":"verify-webhook-signatures","title":"Verify webhook signatures against the deterministic sample","owner":"partner_engineer","requiredScopes":["webhooks:write"],"endpoint":"POST /api/v1/partner/webhooks/verify","completionSignal":"Partner code validates x-senior-guru-signature using HMAC-SHA256 over timestamp.rawBody.","blocker":"Parsing JSON before verifying the raw body can invalidate signatures and blocks production approval."},{"key":"review-production-promotion","title":"Review sandbox evidence before live promotion","owner":"partner_ops","requiredScopes":["providers:read","events:read","usage:read","webhooks:write"],"endpoint":"GET /api/v1/admin/api-usage-analytics","completionSignal":"Admin usage analytics, webhook delivery evidence, link-health, and OpenAPI coverage are reviewed.","blocker":"Production mode remains blocked until owner approves partner purpose, scopes, rate limits, and webhook events."}],"nextActions":["Create or confirm a sandbox API client in the admin Open API console.","Run provider, event, usage, and webhook signature checks from the partner environment.","Export usage and webhook evidence before requesting production promotion."]},"changelog":{"generatedAt":"2026-06-07T20:31:29.007Z","currentVersion":"0.1.0","policy":{"preOneDotZero":"Partner APIs are pre-1.0 and require OpenAPI, changelog, usage evidence, and owner approval review before production promotion.","deprecationNoticeDays":90,"breakingChangeRule":"Breaking partner API changes require a changelog entry, OpenAPI update, migration note, and owner-approved partner notification before rollout."},"entries":[{"version":"0.1.0","releasedAt":"2026-05-14","status":"current","summary":"Initial governed partner API foundation for sandbox provider/event reads, usage evidence, webhook verification, developer docs, and onboarding readiness.","additions":["Scoped partner API key authentication with rate-limit headers and sandbox-mode response metadata.","Provider and event read endpoints for approved partner integrations.","Partner usage analytics with JSON and CSV evidence export.","Webhook signing guide, signature verification endpoint, replay evidence export, and SDK examples.","Sandbox onboarding checklist with production promotion blockers and evidence signals."],"breakingChanges":[],"migrationNotes":["Use x-senior-guru-api-key for all partner calls.","Treat all 0.x endpoints as pre-1.0 and verify OpenAPI metadata before production promotion.","Keep sandbox clients in sandboxMode=true until owner approval records partner purpose, scopes, rate limits, and webhook events."],"affectedEndpoints":["GET /api/v1/partner/providers","GET /api/v1/partner/providers/{id}","GET /api/v1/partner/providers/{id}/visibility","GET /api/v1/partner/providers/{id}/reputation-readiness","GET /api/v1/partner/providers/{id}/review-summary","GET /api/v1/partner/providers/{id}/event-summary","GET /api/v1/partner/providers/{id}/community-summary","GET /api/v1/partner/providers/{id}/ad-summary","GET /api/v1/partner/providers/{id}/campaign-summary","GET /api/v1/partner/providers/{id}/newsletter-summary","GET /api/v1/partner/events","GET /api/v1/partner/events/{id}/analytics","GET /api/v1/partner/reviews","GET /api/v1/partner/community/posts","GET /api/v1/partner/newsroom/articles","GET /api/v1/partner/newsroom/newsletters","GET /api/v1/partner/newsroom/performance","GET /api/v1/partner/newsroom/readiness","GET /api/v1/partner/newsroom/sources","GET /api/v1/partner/ads/placements","GET /api/v1/partner/aggregation/readiness","GET /api/v1/partner/campaigns","POST /api/v1/partner/claims","GET /api/v1/partner/claims/{id}","POST /api/v1/partner/claims/{id}/verification-evidence","GET /api/v1/partner/usage","GET /api/v1/partner/onboarding-checklist","GET /api/v1/partner/developer-docs","GET /api/v1/partner/webhooks/signing-guide","POST /api/v1/partner/webhooks/verify"]},{"version":"0.2.0","releasedAt":"planned","status":"planned","summary":"Planned partner evidence release for sandbox evidence export, versioned response envelopes, and SDK package publishing guidance.","additions":["Sandbox evidence bundle export for provider, events, usage, webhook, and link-health checks.","Explicit response envelope version metadata for partner routes.","Package publishing plan for signed webhook verification helpers."],"breakingChanges":[],"migrationNotes":["No breaking changes are planned for 0.2.0.","Partners should begin storing usage and webhook evidence ids so evidence bundles can reconcile prior sandbox runs."],"affectedEndpoints":["GET /api/v1/partner/usage","GET /api/v1/partner/developer-docs","GET /api/v1/partner/changelog"]}],"nextActions":["Review the current changelog before issuing or promoting partner keys.","Use OpenAPI and the sandbox checklist to validate endpoint behavior for each partner environment.","Capture partner evidence before adopting planned 0.2.0 response metadata or SDK packages."]},"sdkPackagePlan":{"generatedAt":"2026-06-07T20:31:29.007Z","title":"Webhook SDK Package Publishing Plan","objective":"Package the webhook signature verification examples into maintained SDK helpers without weakening raw-body verification, secret custody, or partner audit evidence.","status":"planned","packages":[{"language":"node","packageName":"@theseniorguru/webhooks","status":"planned","publicModule":"verifySeniorGuruWebhookSignature","responsibilities":["Verify x-senior-guru-signature using HMAC-SHA256 and timing-safe digest comparison.","Enforce timestamp tolerance before application JSON parsing.","Return typed verification results with failure reasons for audit logging."],"releaseGate":"Publish only after npm organization ownership, package provenance, 2FA, README review, and signed release workflow are approved."},{"language":"python","packageName":"theseniorguru-webhooks","status":"planned","publicModule":"verify_senior_guru_webhook_signature","responsibilities":["Verify x-senior-guru-signature using hmac.compare_digest.","Keep raw-body verification separate from framework JSON parsing.","Expose deterministic sample tests matching the live signing-guide payload."],"releaseGate":"Publish only after PyPI ownership, trusted publishing, README review, and signed release workflow are approved."}],"requiredSecurityControls":["No SDK stores API keys or webhook signing secrets.","Every helper accepts raw body, signature header, signing secret, and optional tolerance seconds from the caller.","Digest comparison must remain timing-safe in each language runtime.","Package release requires owner-approved registry credentials and 2FA or trusted publishing.","Release artifacts must include deterministic tests generated from /api/v1/partner/webhooks/signing-guide."],"releaseChecklist":["Reserve package names in npm and PyPI under owner-controlled accounts.","Create package READMEs from the live signing guide and changelog.","Add CI tests that recompute the deterministic sample signature.","Document framework-specific raw-body capture examples without handling secrets.","Publish a signed prerelease before linking packages from developer docs."],"ownerBlockers":["Confirm npm organization and PyPI project ownership.","Approve package names, support email, repository URL, and release signer.","Approve whether SDK package publishing happens before or after the 0.2.0 partner evidence release."],"nextActions":["Keep inline SDK examples as the production-safe integration path until registry ownership is approved.","Prepare package READMEs and deterministic tests from the live signing-guide sample.","Add owner approvals before publishing package URLs in public developer docs."]},"sandboxEvidence":{"generatedAt":"2026-06-07T20:31:29.008Z","title":"Partner Sandbox Evidence Export","status":"ready_for_partner_review","currentVersion":"0.1.0","linkHealth":{"status":"passed","total":255,"invalid":0},"totals":{"rows":74,"onboardingSteps":31,"partnerEndpoints":38,"apiVersions":2,"ownerBlockers":3},"reviewGates":["Confirm sandbox API client, key custody, and required scopes before partner testing.","Export usage analytics separately from /api/v1/partner/usage?format=csv with the partner key.","Attach webhook replay evidence when webhooks are part of the partner promotion request.","Resolve owner blockers before SDK package links or production-mode partner clients are published."],"rows":[{"evidenceType":"onboarding_step","subject":"create-sandbox-client","status":"required","owner":"platform_admin","endpoint":"POST /api/v1/admin/api-clients","summary":"Client has sandboxMode=true, status=active, rate limit, owner type, and approved scopes.","blocker":"Do not issue live-mode clients until partner business owner, data use, and webhook purpose are approved."},{"evidenceType":"onboarding_step","subject":"mint-sandbox-key","status":"required","owner":"platform_admin","endpoint":"POST /api/v1/admin/api-clients/{id}/keys","summary":"Key preview is visible in admin records and the full secret was copied once into the partner vault.","blocker":"Lost secrets must be revoked and reissued; backend never exposes stored key material."},{"evidenceType":"onboarding_step","subject":"read-provider-inventory","status":"required","owner":"partner_engineer","endpoint":"GET /api/v1/partner/providers","summary":"Response includes provider records and rate-limit headers with x-senior-guru-sandbox=true.","blocker":"403 responses mean the key is missing providers:read scope or the client is paused/revoked."},{"evidenceType":"onboarding_step","subject":"read-provider-detail","status":"required","owner":"partner_engineer","endpoint":"GET /api/v1/partner/providers/{id}","summary":"Response includes one approved provider record, source provenance, lookup metadata, partner envelope headers, and excludes internal admin notes or claim verification evidence.","blocker":"Do not hydrate partner provider profiles from non-approved statuses or from internal claim verification evidence."},{"evidenceType":"onboarding_step","subject":"read-provider-visibility","status":"required","owner":"partner_ops","endpoint":"GET /api/v1/partner/providers/{id}/visibility","summary":"Response includes aggregate provider readiness scores, metrics, missing public profile fields, and next-best-action labels without entitlement keys, internal URLs, or claim evidence.","blocker":"Do not use provider readiness evidence for partner ranking when internal entitlements, audit records, or claim verification evidence are required by the partner workflow."},{"evidenceType":"onboarding_step","subject":"read-provider-reputation-readiness","status":"required","owner":"partner_ops","endpoint":"GET /api/v1/partner/providers/{id}/reputation-readiness","summary":"Response includes aggregate review, campaign, sentiment, blocker, and next-action readiness with partner envelope headers and no reviewer emails, request recipients, moderation notes, or internal action URLs.","blocker":"Do not use reputation readiness externally when the partner workflow requires raw reviewer identity, moderation evidence, or recipient-level request records."},{"evidenceType":"onboarding_step","subject":"read-provider-review-summary","status":"required","owner":"partner_ops","endpoint":"GET /api/v1/partner/providers/{id}/review-summary","summary":"Response includes aggregate published-review count, rating distribution, source counts, sentiment totals, partner envelope headers, and no reviewer names, emails, body text, moderation status, or recipient details.","blocker":"Do not use review summary output as a raw testimonial feed; use the published reviews endpoint when approved display attribution is required."},{"evidenceType":"onboarding_step","subject":"read-provider-event-summary","status":"required","owner":"partner_ops","endpoint":"GET /api/v1/partner/providers/{id}/event-summary","summary":"Response includes provider-scoped event counts, RSVP totals, promotion totals, ad metrics, public event references, partner envelope headers, and no attendee names, emails, phones, consent payloads, or per-RSVP rows.","blocker":"Do not share provider event performance externally if the partner workflow requires attendee-level consent evidence or raw RSVP records."},{"evidenceType":"onboarding_step","subject":"read-provider-community-summary","status":"required","owner":"partner_ops","endpoint":"GET /api/v1/partner/providers/{id}/community-summary","summary":"Response includes provider-scoped published post counts, sponsorship disclosure totals, post type/location distribution, public post references, partner envelope headers, and no author names, body text, comments, member identity, or moderation status.","blocker":"Do not use community summary output as a raw community feed; use the published community posts endpoint when approved post display rules are required."},{"evidenceType":"onboarding_step","subject":"read-provider-ad-summary","status":"required","owner":"partner_ops","endpoint":"GET /api/v1/partner/providers/{id}/ad-summary","summary":"Response includes provider-scoped aggregate delivery totals, placement rollups, ad health, recommendations, partner envelope headers, and no raw creative payloads, destination URLs, visitor context, request IDs, or row-level impression/click records.","blocker":"Do not use ad summary output for creative rendering; use approved ad placement inventory and preserve disclosure labels before rendering sponsored placements."},{"evidenceType":"onboarding_step","subject":"read-provider-campaign-summary","status":"required","owner":"partner_ops","endpoint":"GET /api/v1/partner/providers/{id}/campaign-summary","summary":"Response includes provider-scoped campaign totals, asset approval totals, metric rollups, type/status/channel distributions, public campaign references, partner envelope headers, and no campaign audience payloads, asset bodies, asset payloads, metric payloads, or row-level metric records.","blocker":"Do not mirror campaign assets or audience rules from summary output; use approved campaign inventory and owner-reviewed channel rules before external display."},{"evidenceType":"onboarding_step","subject":"read-community-events","status":"required","owner":"partner_engineer","endpoint":"GET /api/v1/partner/events","summary":"Response includes event records with community-safe metadata for sandbox validation.","blocker":"Do not mirror events publicly until partner display rules and sponsorship disclosures are reviewed."},{"evidenceType":"onboarding_step","subject":"read-event-analytics","status":"required","owner":"partner_ops","endpoint":"GET /api/v1/partner/events/{id}/analytics","summary":"Response includes aggregate RSVP, promotion, and ad metrics with partner envelope headers and no attendee names, emails, phones, or consent payloads.","blocker":"Do not share event performance externally if attendee PII, consent payloads, or provider-only notes are required by the partner workflow."},{"evidenceType":"onboarding_step","subject":"read-published-reviews","status":"required","owner":"partner_engineer","endpoint":"GET /api/v1/partner/reviews","summary":"Response includes only published reviews, provider context, pagination metadata, and no reviewer email field.","blocker":"Do not syndicate reviews until partner display rules, attribution, and moderation status handling are approved."},{"evidenceType":"onboarding_step","subject":"read-community-posts","status":"required","owner":"partner_engineer","endpoint":"GET /api/v1/partner/community/posts","summary":"Response includes only published community posts, optional location/topic filters, pagination metadata, and disclosure labels for sponsored posts.","blocker":"Do not mirror community content until partner moderation display rules and sponsored-content disclosure handling are approved."},{"evidenceType":"onboarding_step","subject":"read-newsroom-articles","status":"required","owner":"partner_engineer","endpoint":"GET /api/v1/partner/newsroom/articles","summary":"Response includes only published articles, preview body text, source links, topic/audience filters, pagination metadata, and partner envelope headers.","blocker":"Do not syndicate editorial content unless attribution, preview-only body display, and partner content-use approval are preserved."},{"evidenceType":"onboarding_step","subject":"read-newsroom-newsletters","status":"required","owner":"partner_engineer","endpoint":"GET /api/v1/partner/newsroom/newsletters","summary":"Response includes approved, scheduled, or sent newsletter metadata, linked article references, pagination metadata, and no recipient or delivery-attempt records.","blocker":"Do not syndicate newsletter editions unless attribution, unsubscribe expectations, and recipient privacy boundaries are preserved."},{"evidenceType":"onboarding_step","subject":"read-provider-newsletter-summary","status":"required","owner":"partner_ops","endpoint":"GET /api/v1/partner/providers/{id}/newsletter-summary","summary":"Response includes provider-scoped newsletter delivery and performance rollups, blocker evidence, and no recipient identities, delivery payload previews, delivery attempt IDs, audience segments, or raw metric payloads.","blocker":"Do not use provider newsletter analytics unless aggregate-only reporting and recipient privacy boundaries are preserved."},{"evidenceType":"onboarding_step","subject":"read-newsroom-performance","status":"required","owner":"partner_ops","endpoint":"GET /api/v1/partner/newsroom/performance","summary":"Response includes aggregate totals, channel rollups, top article/newsletter rows, partner envelope metadata, and no raw metric payloads or recipient records.","blocker":"Do not use partner content performance evidence unless aggregation-only reporting and recipient privacy boundaries are preserved."},{"evidenceType":"onboarding_step","subject":"read-newsroom-readiness","status":"required","owner":"partner_ops","endpoint":"GET /api/v1/partner/newsroom/readiness","summary":"Response includes aggregate source, article, derivative, and blocker summaries with no draft bodies, source item bodies, or admin review notes.","blocker":"Do not enable partner syndication when readiness status is blocked or action_required without partner content-use and editorial approval."},{"evidenceType":"onboarding_step","subject":"read-newsroom-sources","status":"required","owner":"partner_engineer","endpoint":"GET /api/v1/partner/newsroom/sources","summary":"Response includes only approved source records, attribution notes, pagination metadata, and excludes pending, blocked, legal-review, and raw source item bodies.","blocker":"Do not attribute or mirror newsroom content from sources that are pending, blocked, or awaiting legal review."},{"evidenceType":"onboarding_step","subject":"read-ad-placements","status":"required","owner":"partner_engineer","endpoint":"GET /api/v1/partner/ads/placements","summary":"Response includes active placements, surfaces, disclosure labels, pagination metadata, and optional delivery preview data when includeCreatives=true.","blocker":"Do not render paid placements unless the partner UI preserves disclosure labels and separates organic ranking from sponsored placement."},{"evidenceType":"onboarding_step","subject":"read-aggregation-readiness","status":"required","owner":"partner_ops","endpoint":"GET /api/v1/partner/aggregation/readiness","summary":"Response includes aggregate source, import, crawler, launch target, and quality health with no source IDs, base URLs, terms notes, queue rows, import batches, crawl jobs, or quality flag rows.","blocker":"Do not market inventory freshness or launch coverage claims unless aggregate readiness is ready or action_required blockers are accepted."},{"evidenceType":"onboarding_step","subject":"read-published-campaigns","status":"required","owner":"partner_engineer","endpoint":"GET /api/v1/partner/campaigns","summary":"Response includes published non-blocked campaigns, provider/type/status filters, pagination metadata, and optional metrics when includeMetrics=true.","blocker":"Do not mirror campaign content until partner campaign purpose, channel rules, consent boundaries, and attribution are approved."},{"evidenceType":"onboarding_step","subject":"submit-provider-claim","status":"required","owner":"partner_engineer","endpoint":"POST /api/v1/partner/claims","summary":"Response includes the created provider claim, verification checklist, next action, partner envelope metadata, and API audit evidence.","blocker":"Do not submit third-party correction claims without claimant authority, provider identity evidence, and partner data-use approval."},{"evidenceType":"onboarding_step","subject":"poll-provider-claim-status","status":"required","owner":"partner_engineer","endpoint":"GET /api/v1/partner/claims/{id}?claimantEmail={email}","summary":"Response includes the claim, checklist, next action, and partner envelope metadata only when the claimant email matches.","blocker":"Do not expose claim status in partner systems unless the claimant email match and partner data-use approval are both preserved."},{"evidenceType":"onboarding_step","subject":"submit-provider-claim-evidence","status":"required","owner":"partner_engineer","endpoint":"POST /api/v1/partner/claims/{id}/verification-evidence","summary":"Response includes safe verification attempt status and refreshed claim checklist after claimantEmail match and attestation acceptance; raw evidence, attempt IDs, verification targets, and policy decisions are excluded.","blocker":"Do not submit or display claim evidence unless the claimant email matches the original claim and the claimant has accepted the attestation."},{"evidenceType":"onboarding_step","subject":"verify-usage-evidence","status":"required","owner":"partner_ops","endpoint":"GET /api/v1/partner/usage?format=csv","summary":"Usage export shows allowed, blocked, and rate-limited calls for partner operations review.","blocker":"Missing usage evidence blocks production promotion because launch operations cannot audit partner access."},{"evidenceType":"onboarding_step","subject":"create-webhook-subscription","status":"required","owner":"platform_admin","endpoint":"POST /api/v1/admin/webhook-subscriptions","summary":"Subscription uses HTTPS, approved event types, active status, and a one-time signing secret.","blocker":"HTTP targets, unsupported events, and missing signing-secret custody block subscription approval."},{"evidenceType":"onboarding_step","subject":"verify-webhook-signatures","status":"required","owner":"partner_engineer","endpoint":"POST /api/v1/partner/webhooks/verify","summary":"Partner code validates x-senior-guru-signature using HMAC-SHA256 over timestamp.rawBody.","blocker":"Parsing JSON before verifying the raw body can invalidate signatures and blocks production approval."},{"evidenceType":"onboarding_step","subject":"review-production-promotion","status":"required","owner":"partner_ops","endpoint":"GET /api/v1/admin/api-usage-analytics","summary":"Admin usage analytics, webhook delivery evidence, link-health, and OpenAPI coverage are reviewed.","blocker":"Production mode remains blocked until owner approves partner purpose, scopes, rate limits, and webhook events."},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/ads/placements","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/ads/placements","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/aggregation/readiness","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/aggregation/readiness","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/campaigns","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/campaigns","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/changelog","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/changelog","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/claims","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/claims","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/claims/{id}","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/claims/{id}","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/claims/{id}/verification-evidence","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/claims/{id}/verification-evidence","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/community/posts","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/community/posts","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/developer-docs","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/developer-docs","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/events","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/events","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/events/{id}/analytics","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/events/{id}/analytics","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/newsroom/articles","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/newsroom/articles","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/newsroom/newsletters","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/newsroom/newsletters","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/newsroom/performance","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/newsroom/performance","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/newsroom/readiness","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/newsroom/readiness","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/newsroom/sources","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/newsroom/sources","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/onboarding-checklist","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/onboarding-checklist","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/pagination-evaluation","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/pagination-evaluation","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/pagination-volume-evidence","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/pagination-volume-evidence","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/providers","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/providers","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/providers/{id}","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/providers/{id}","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/providers/{id}/ad-summary","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/providers/{id}/ad-summary","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/providers/{id}/campaign-summary","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/providers/{id}/campaign-summary","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/providers/{id}/community-summary","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/providers/{id}/community-summary","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/providers/{id}/event-summary","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/providers/{id}/event-summary","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/providers/{id}/newsletter-summary","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/providers/{id}/newsletter-summary","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/providers/{id}/reputation-readiness","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/providers/{id}/reputation-readiness","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/providers/{id}/review-summary","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/providers/{id}/review-summary","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/providers/{id}/visibility","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/providers/{id}/visibility","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/response-envelope","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/response-envelope","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/response-pagination","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/response-pagination","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/reviews","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/reviews","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/sandbox-evidence","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/sandbox-evidence","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/sdk-package-plan","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/sdk-package-plan","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/sdk-publish-readiness","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/sdk-publish-readiness","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/usage","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/usage","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/webhooks/signing-guide","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/webhooks/signing-guide","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"partner_endpoint","subject":"/api/v1/partner/webhooks/verify","status":"documented","owner":"partner_engineer","endpoint":"/api/v1/partner/webhooks/verify","summary":"Partner endpoint is present in the live OpenAPI catalog.","blocker":""},{"evidenceType":"api_version","subject":"0.1.0","status":"current","owner":"partner_ops","endpoint":"GET /api/v1/partner/changelog","summary":"Initial governed partner API foundation for sandbox provider/event reads, usage evidence, webhook verification, developer docs, and onboarding readiness.","blocker":""},{"evidenceType":"api_version","subject":"0.2.0","status":"planned","owner":"partner_ops","endpoint":"GET /api/v1/partner/changelog","summary":"Planned partner evidence release for sandbox evidence export, versioned response envelopes, and SDK package publishing guidance.","blocker":""},{"evidenceType":"sdk_owner_blocker","subject":"sdk-blocker-1","status":"blocked_pending_owner_approval","owner":"platform_admin","endpoint":"GET /api/v1/partner/sdk-package-plan","summary":"Confirm npm organization and PyPI project ownership.","blocker":"Confirm npm organization and PyPI project ownership."},{"evidenceType":"sdk_owner_blocker","subject":"sdk-blocker-2","status":"blocked_pending_owner_approval","owner":"platform_admin","endpoint":"GET /api/v1/partner/sdk-package-plan","summary":"Approve package names, support email, repository URL, and release signer.","blocker":"Approve package names, support email, repository URL, and release signer."},{"evidenceType":"sdk_owner_blocker","subject":"sdk-blocker-3","status":"blocked_pending_owner_approval","owner":"platform_admin","endpoint":"GET /api/v1/partner/sdk-package-plan","summary":"Approve whether SDK package publishing happens before or after the 0.2.0 partner evidence release.","blocker":"Approve whether SDK package publishing happens before or after the 0.2.0 partner evidence release."}]},"responseEnvelope":{"generatedAt":"2026-06-07T20:31:29.008Z","title":"Partner Response Envelope Contract","currentVersion":"2026-05-14.partner.v1","envelope":{"version":"2026-05-14.partner.v1","dataPath":"data","metaPath":"meta","errorPath":"error"},"requiredHeaders":["x-senior-guru-envelope-version","x-senior-guru-api-client","x-senior-guru-sandbox","x-ratelimit-limit","x-ratelimit-window"],"successShape":{"data":"The endpoint-specific payload. Arrays remain arrays; objects remain typed resource objects.","meta":{"apiClientId":"Authenticated partner API client id.","sandboxMode":"Boolean flag showing whether the client is sandbox-only.","responseEnvelope":{"version":"2026-05-14.partner.v1","dataPath":"data","metaPath":"meta","errorPath":"error"}}},"errorShape":{"error":"Safe partner-facing error message.","headers":["x-senior-guru-api-status","x-senior-guru-envelope-version"]},"versioningRules":["Partner clients should read x-senior-guru-envelope-version on every authenticated response.","Additive fields may appear inside meta without a breaking version change.","Moving data, meta, or error paths requires a changelog entry, OpenAPI update, migration note, and owner-approved partner notification.","CSV exports keep stable column headers and use content-disposition filenames for evidence capture."],"nextActions":["Update partner smoke tests to assert the envelope header and meta.responseEnvelope.version.","Use the changelog before adopting any future envelope version.","Attach envelope-version evidence to sandbox promotion exports."]},"responsePagination":{"generatedAt":"2026-06-07T20:31:29.008Z","title":"Partner Response Pagination Contract","status":"active","queryParameters":{"page":{"type":"integer","default":1,"min":1,"max":10000},"pageSize":{"type":"integer","default":50,"min":1,"max":100}},"paginatedEndpoints":["GET /api/v1/partner/providers","GET /api/v1/partner/events","GET /api/v1/partner/reviews","GET /api/v1/partner/community/posts","GET /api/v1/partner/ads/placements","GET /api/v1/partner/campaigns"],"metaShape":{"pagination":{"page":"Current normalized page.","pageSize":"Current normalized page size.","total":"Total matching records before pagination.","pageCount":"Total page count for the current page size.","hasNextPage":"Whether a next page exists.","hasPreviousPage":"Whether a previous page exists.","nextPage":"Next page number or null.","previousPage":"Previous page number or null.","offset":"Zero-based row offset used to slice the result set."}},"versioningRules":["Pagination metadata is additive inside meta and follows the current response-envelope version.","Clients should keep using data as the page payload and meta.pagination for traversal.","Server-side maximum pageSize is 100 to protect production response sizes.","Out-of-range page requests are normalized to the last available page."],"nextActions":["Update partner smoke tests to request pageSize=2 and assert meta.pagination.","Use page and pageSize for provider/event inventory sync jobs instead of assuming full dumps.","Add cursor pagination only after production inventory volume and partner sync frequency justify it."]},"paginationEvaluation":{"generatedAt":"2026-06-07T20:31:29.008Z","title":"Partner Cursor Pagination Evaluation","status":"offset_pagination_current","recommendation":"Keep the active page/pageSize contract until production inventory volume and partner sync cadence justify cursor tokens.","currentContract":{"status":"active","pageSizeMax":100,"endpoints":["GET /api/v1/partner/providers","GET /api/v1/partner/events","GET /api/v1/partner/reviews","GET /api/v1/partner/community/posts","GET /api/v1/partner/ads/placements","GET /api/v1/partner/campaigns"]},"totals":{"evaluatedEndpoints":9,"cursorCandidateEndpoints":9,"highRiskEndpoints":1},"migrationGates":["Confirm stable per-resource ordering keys before adding cursor parameters.","Keep data and meta.pagination paths additive under the active partner response envelope.","Publish changelog and developer-docs examples before accepting cursor query parameters.","Run production partner smoke tests against page/pageSize and cursor traversal before promotion."],"compatibilityRules":["Do not remove page or pageSize when cursor pagination is introduced.","Cursor responses must keep pageSize, hasNextPage, and response envelope headers.","Cursor tokens must be opaque, short-lived, tenant-safe, and free of PHI or partner secrets.","CSV evidence exports must show which traversal mode generated the export."],"rows":[{"endpoint":"GET /api/v1/partner/providers","currentMode":"page_pageSize_offset","stableSort":"name_ascending","cursorCandidate":"name+id","risk":"low","productionTrigger":"Provider inventory exceeds page/pageSize traversal needs for partner syncs."},{"endpoint":"GET /api/v1/partner/events","currentMode":"page_pageSize_offset","stableSort":"startDate_ascending","cursorCandidate":"startDate+id","risk":"medium","productionTrigger":"Event syncs require incremental windows across large regional calendars."},{"endpoint":"GET /api/v1/partner/reviews","currentMode":"page_pageSize_offset","stableSort":"submittedAt_descending","cursorCandidate":"submittedAt+id","risk":"medium","productionTrigger":"Review exports need high-volume incremental sync without duplicate rows."},{"endpoint":"GET /api/v1/partner/community/posts","currentMode":"page_pageSize_offset","stableSort":"publishedAt_descending","cursorCandidate":"publishedAt+id","risk":"medium","productionTrigger":"Community partner feeds need stable pagination across frequent moderation changes."},{"endpoint":"GET /api/v1/partner/newsroom/articles","currentMode":"page_pageSize_offset","stableSort":"publishedAt_descending","cursorCandidate":"publishedAt+id","risk":"medium","productionTrigger":"Article syndication partners need incremental published-content pulls."},{"endpoint":"GET /api/v1/partner/newsroom/newsletters","currentMode":"page_pageSize_offset","stableSort":"scheduledFor_descending","cursorCandidate":"scheduledFor+id","risk":"medium","productionTrigger":"Newsletter archive integrations require stable historical traversal."},{"endpoint":"GET /api/v1/partner/newsroom/sources","currentMode":"page_pageSize_offset","stableSort":"name_ascending","cursorCandidate":"name+id","risk":"low","productionTrigger":"Approved source registry grows beyond simple page traversal."},{"endpoint":"GET /api/v1/partner/ads/placements","currentMode":"page_pageSize_offset","stableSort":"placementId_ascending","cursorCandidate":"placementId","risk":"low","productionTrigger":"Ad inventory partners need frequent placement syncs with low payload churn."},{"endpoint":"GET /api/v1/partner/campaigns","currentMode":"page_pageSize_offset","stableSort":"updatedAt_descending","cursorCandidate":"updatedAt+id","risk":"high","productionTrigger":"Campaign status changes create duplicate or skipped records under offset pagination."}]},"operationalControls":["All partner requests are audited by client, key, scope, subject, status, and rate-limit result.","CSV usage evidence is available from /api/v1/partner/usage?format=csv with usage:read scope.","Webhook subscriptions require HTTPS targets and expose signing secrets only once at creation.","Failed webhook deliveries can be retried; historical deliveries can be replayed as fresh queued records with audit evidence.","Replay evidence exports can be filtered by API client, event type, source status, replay status, subject, date window, and audited-only rows."],"nextActions":["Issue a scoped sandbox API key from the admin Open API console.","Call the providers or events endpoint with x-senior-guru-api-key.","Create a webhook subscription and verify signatures against the signing guide sample.","Review usage analytics and delivery evidence before moving a partner out of sandbox mode."]}}