Customer agreement API and MCP

Review an issued Order Form, verify the accepting person's email and deliberately accept the standard agreement. Acceptance completes it without a Lightmeter signer or countersignature. Download the retained accepted PDF; automatic copies go to the verified acceptor and Lightmeter's invoice inbox. Copy delivery and first-invoice confirmation are separate from acceptance.

Access and consent

The invitation API uses a private capability in the path: /v1/onboarding/invites/{token}/native-agreement. Keep it out of logs, public links and issue descriptions. A workspace login or organization API key alone does not grant that invitation capability. For MCP, sign in to /mcp/native-agreements in Beam with the same account as the MCP connection and link the invitation privately. MCP then uses an access_id bound to that account. An access ID alone grants no access to another account. Do not paste invitation tokens or email codes into the assistant.

Read the server's exact acceptance_statement and frozen terms before acceptance. An agent may submit binding acceptance only after the human explicitly accepts that statement for the named company. Email verification, a forwarded link or a payment action does not supply that consent.

An acceptance-only representative link cannot pay, refresh payment or set up a workspace. The original contact retains those actions. An existing-workspace agreement-only invitation preserves billing and service; it creates no new subscription or setup, and does not reset the service or term clock.

A verification code is valid for 60 minutes and permits five attempts. After successful verification, the private verification token is valid for 60 minutes. Use the returned expires_at and verified_until deadlines; previously issued codes and tokens keep their stored expiry. Verification does not extend the offer's validity or permit accepting a replaced offer.

Invitation operations

Paths below are relative to the invitation root. MCP tools use access_id instead of the invitation token. POST tools take the documented JSON body in payload, except that email verification happens privately in Beam. Binding acceptance, Checkout creation/recovery and payment reconciliation are website/API operations only; no MCP tool performs them or returns a payment handoff link.

APIMCP toolBody or result
GET invitation rootonboarding_native_agreement_getCurrent offer, frozen source/terms, statement, acceptance, copies, payment and allowed actions. MCP omits acceptance/checkout/payment-refresh from its allowed actions. Without access_id, MCP lists this account's linked invitations and the private linking page.
POST /verification-codeonboarding_native_agreement_verification_code_sendagreement_id, email; returns challenge, expiry and resend time.
POST /verify-emailonboarding_native_agreement_email_verifyThe invitation API accepts agreement_id, challenge_id, code and returns a private verification token. MCP checks verification status and directs the person to Beam to enter the code; it accepts and returns no code or verification token.
POST /acceptWebsite/API onlyAcceptance body below; returns the authoritative agreement view.
POST /acceptance-statusonboarding_native_agreement_acceptance_statusagreement_id, request_id; resolves the original request without accepting.
POST /delegateonboarding_native_agreement_delegateagreement_id, name, email; emails a separate acceptance-only link.
POST /copiesonboarding_native_agreement_copies_retryEmpty object; retries failed/unknown accepted-PDF copies. An unknown send can duplicate an email.
POST /checkoutWebsite/API onlyEmpty object; create/recover Checkout for an eligible completed new-customer agreement, returning url.
POST /payment/refreshWebsite/API onlyEmpty object; reconcile authoritative reserved-Checkout/first-invoice confirmation and complete the recurring subscription when eligible.
GET /pdf?document=issued|executedUse the chunk tool belowExact retained PDF bytes. The compatibility name executed identifies the accepted artifact.
GET /pdf/chunks?document=issued|executed&index=0onboarding_native_agreement_pdf_chunk_getMCP arguments: document, chunk_index. Decode and assemble chunks, then verify total bytes and SHA-256.

Private account linking

The authenticated browser API uses /authenticated/v1/onboarding/native-access and requires a signed-in user, including invitation recipients who do not yet have a workspace. GET lists that user's links; POST accepts {"invite_token":"<private-invitation-token>"} and returns an access_id. GET /{access_id} reads the current agreement and verification status, while DELETE /{access_id} disconnects that invitation from the signed-in user, including any earlier linked IDs. POST /{access_id}/verification-code accepts agreement_id, email; POST /{access_id}/verify-email accepts agreement_id, challenge_id, code and returns verification status without a bearer token.

Setup invitations can be linked before a native agreement exists. For these links, GET /{access_id} returns setup_only=true, without an agreement or email-code step. onboarding_industry_keywords_suggest accepts that account-bound access_id and a bounded payload containing website_url, with optional company_name and root_keywords. Call with empty arguments to list linked invitations and receive the private linking page; generation requires both access_id and payload. The same invitation eligibility, agreement/payment gates and generation allowance as the website/API apply; representative agreement links do not authorize Setup. Suggestions do not save keywords or start a build.

Reconnecting the same current capability reuses its active access ID and verification state. A changed capability receives a fresh ID and revokes the previous one; an earlier representative ID never gains original-contact permissions. Listing returns all active invitations linked to the signed-in user.

The linked record stores capability fingerprints, not the invitation or verification secrets. Revocation, invitation expiry, signing-key rotation and replacement-offer rules still apply. Original-contact links follow the current offer; representative links retain their delegated revision. Verification of an earlier offer cannot authorize acceptance of its replacement.

Accept and recover

Use a UUID for request_id. Send the person's name, verified-email token, confirmed company address and legal-notice email. Do not collect a job title or company number. The example below is the invitation API body. Binding acceptance remains in the website/API flow and is not exposed through MCP.

{
  "agreement_id": "<issued-agreement-UUID>",
  "request_id": "<acceptance-request-UUID>",
  "verification_token": "<private-verified-email-token>",
  "name": "<person-accepting>",
  "customer_address": "<confirmed-company-address>",
  "notice_email": "<legal-notice-email>",
  "authorized": true
}

If the acceptance response is lost or uncertain, keep the original UUID and call acceptance-status. It returns acceptance_resolution=accepted or definite_non_acceptance. The latter permanently fences that request UUID, including a delayed original request. Review the current offer before a deliberate retry with a new UUID. Repeating the status operation is safe.

Structured acceptance errors with operation_resolution=definite_non_acceptance confirm that request did not accept. A timeout, transport failure or unqualified server error leaves an unknown result. Superseded or expired offers cannot be accepted; a replacement requires renewed review and consent.

Read the authoritative state

The view includes id, mode, status, revision_number, commercial_terms, terms_version, source_release, acceptance_statement, terms_html, acceptance, copy_delivery, payment, acceptance_only, agreement_only, allowed_actions. Render the exact server statement and allowed actions. Revision numbers need a visible label only from 2. Custom completion is recorded separately from customer acceptance.

payment.status is not_started, waiting or confirmed. checked_at is the last provider check; confirmed_at, service_start_date, billing_day are authoritative only after confirmation. first_invoice_kind distinguishes paid_invoice from zero_balance_invoice.

Native Checkout offers reusable cards. For a positive first invoice, actual Stripe paid confirmation starts service, the Initial Service Term and anniversary. For a zero-total first invoice, a securely saved future payment method and an actual Stripe-confirmed zero-balance invoice are both required. Acceptance or no_payment_required alone cannot unlock setup. Optional earliest start blocks Checkout; the eligible date does not independently start the service clock.

Workspace archive

After onboarding, use Settings → Agreements or the workspace-scoped agreement API. Use the current organization's API-key authorization for /api/v1/agreements, /api/v1/agreements/{agreement_id}/pdf?document=issued|executed, and /api/v1/agreements/{agreement_id}/pdf/chunk?document=issued|executed&index=0.

MCP equivalents are workspace_agreements_list and workspace_agreement_pdf_chunk_get, with workspace_id, plus agreement_id, document, chunk_index for a PDF. Every read requires current workspace access. Assemble content_base64 in index order and verify total_bytes and sha256; each chunk includes chunk_count and filename.

Native acceptances, recorded custom completion and historical provider agreements retain their own truthful provenance. Account download reuses stored bytes; it never rebuilds an old contract from today's source.