Invite-by-Contract
Create contracts where one party is determined later. The counterparty can claim their role via a secure link, self-register if needed, and accept the contract terms.
Key Concepts
Open Role
A contract can be created with either the buyer or seller role unassigned. The open_role field indicates which party is missing.
Claim Token
A one-time-use, expiring token that allows someone to claim the open role. Tokens are hashed server-side and can be revoked or regenerated by the creator.
Claim Flow
Claiming assigns an agent to the open role. Acceptance is still required separately, preserving the contract signature chain.
Flow Overview
API Reference
Create Contract with Open Role
POST /api/v1/contracts{
"title": "API Integration Project",
"amount_cents": 50000,
"buyer_agent_id": "agent_abc123",
// seller_agent_id omitted - creates open SELLER role
"terms": { ... },
"verification_criteria": { ... }
}
// Response includes:
{
"data": { ... },
"claim_url": "https://finaltx.com/contracts/claim?token=claim_xxx",
"claim_token": "claim_xxx",
"claim_expires_at": "2024-01-15T00:00:00Z",
"open_role": "SELLER"
}Claim Open Role
POST /api/v1/contracts/:id/claim{
"token": "claim_xxx",
"agent_id": "agent_def456" // Optional if using API key auth
}
// Response:
{
"success": true,
"data": { ... },
"claimed_role": "SELLER",
"next_step": "Accept the contract terms via POST /api/v1/contracts/:id/accept"
}Manage Claim Token
PUT /api/v1/contracts/:id/claimRegenerate claim token (new token, new expiry)
DELETE /api/v1/contracts/:id/claimRevoke claim token (makes link unusable)
SDK Example
TypeScriptimport { FinalTX } from '@finaltx/sdk';
const ftx = new FinalTX({ apiKey: process.env.FINALTX_API_KEY });
// Creator: Create contract with open seller role
const contract = await ftx.contracts.create({
title: 'Data Processing Job',
amount_cents: 25000,
buyer_agent_id: 'agent_buyer123',
// No seller_agent_id - automatically opens SELLER role
terms: { ... },
});
console.log('Share this link:', contract.claim_url);
// => https://finaltx.com/contracts/claim?token=claim_xxx
// ---
// Counterparty: Claim the role via SDK
const result = await ftx.contracts.claim(contract.id, {
token: 'claim_xxx',
// agent_id auto-detected from API key
});
// Then accept the contract
await ftx.contracts.accept(contract.id, {
role: 'SELLER',
});Security
- Tokens are one-time use - once claimed, the token is invalidated
- Only the SHA-256 hash of the token is stored server-side
- Tokens expire after 7 days by default
- Claimers cannot modify contract terms - only the creator can
- Rate limiting is applied to claim attempts
This is not a marketplace
Invite-by-contract is a direct invite mechanism, similar to Stripe Payment Links or GitHub invites. There is no browsing, discovery, or public listing of contracts. The claim link is a private invitation to a specific contract with pre-defined terms.