Agreements – Retrieve Agreement Details¶
When should I use this?¶
Invoke this flow immediately after a user selects an agreement from the list to render a full detail view, confirm readiness before funding, drive participant acceptance, or review arbitration activity. It is the prerequisite for any lifecycle action that depends on the latest snapshot of the agreement.
Purpose¶
Return the complete agreement payload—participants, items, deadlines, funding data, and blockchain references—so integrators can present accurate state and determine which follow-up actions (funding, acceptance, arbitration, unlock) are currently available.
Preconditions¶
- Authentication: The route uses the
populateUsermiddleware. Provide a valid PAYCIFI access token whenever retrieving this off-chain metadata; malformed or expired tokens are rejected. Reading the DShare contract directly on-chain does not require PAYCIFI authentication, but this REST snapshot does. - Access scope: The backend does not enforce participant-based filtering for this endpoint. Clients MUST request only agreements their signed-in user is entitled to view.
- Path parameter:
agreementIdMUST be a valid UUID referencing an existing agreement with an on-chain contract address.
Client Responsibilities¶
- Provide the
agreementIdpath parameter taken from a trusted source (e.g., the list response). Do not guess or expose arbitrary IDs. - Always send the authenticated user’s PAYCIFI token for this REST call; wallets that sign transactions directly on-chain interact with DShare without PAYCIFI tokens, but that happens outside this endpoint.
- Validate the response before enabling critical actions: ensure the participant role (
participantType,owner, statuses) matches the action being surfaced.
API Flow¶
- Client request:
GET /api/v1/agreements/:agreementIdwithAuthorization: Bearer <token>. - Backend validation: The controller checks that
agreementIdexists. If missing, it returns400 missing-agreementId. - Data aggregation:
AgreementsService.fetchAgreementByIdgathers: - Agreement record + currency, fee strategy, totals, status, deadlines, RPC/network references, arbitrator status.
- Participants (payer, providers, arbitrator, contributor roles) including emails, phone numbers,
agreement_status,realisation_status, andownerflag. - Items (prefixed with an "agreement-name" pseudo-item) with provider/payer item statuses, fees, and assignments.
- Arbitration settings (arbitrator profile) and blockchain metadata (
rpcUrl,contractAddress,tokenAddress,createdAtBlock). - Blockchain enrichment: The controller requires a contract address; if absent, it returns
409 agreement-missing-contract-address. Otherwise it callsBlockchainService.getAgreementand attaches cached unlock transaction info (if any) underblockchainAgreement.unlockFundsTxHash. - Response: A consolidated object containing
participants,agreementInfo,agreementItems,arbitrationSettings,blockchain,agreementId, andblockchainAgreement(on-chain snapshot + optional unlock hash). Use this as an off-chain snapshot; every lifecycle action (funding, validation, arbitration, unlock) must still be executed directly on the DShare smart contract.
Example Request¶
GET /api/v1/agreements/d9b6da1a-432c-47d8-8b0d-9ac01aa4f1ce
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Example Response¶
{
"agreementId": "d9b6da1a-432c-47d8-8b0d-9ac01aa4f1ce",
"agreementInfo": {
"title": "Design Sprint Retainer",
"description": "4-week sprint with Nova Studio",
"ownerUserId": "3f6f6b4f-9c7d-4b9b-9f5a-43b0d4c2f101",
"acceptanceDeadline": 1736371200,
"completionDeadline": 1738972800,
"feesPct": 2.5,
"feesConst": 0,
"feePayerStrategy": "payer_covers_all",
"network": "polygon",
"contractAddress": "0xabc123...789",
"currency": "USDC",
"totalAmount": 12000,
"status": "pending",
"arbitratorStatus": null
},
"participants": [
{
"id": "f0629825-ea62-4a79-83e0-020b4b3f07c1",
"user_id": "3f6f6b4f-9c7d-4b9b-9f5a-43b0d4c2f101",
"fullname": "Acme Corp",
"email": "payer@acme.com",
"phone": "+1-415-555-1212",
"information": "Finance desk",
"participant_type": "payer",
"agreement_status": "pending",
"realisation_status": null,
"participantType": "payer",
"owner": true
},
{
"id": "92a4b2b6-45f5-4501-8e71-0d371cbb9011",
"user_id": "92a4b2b6-45f5-4501-8e71-0d371cbb9011",
"fullname": "Studio Nova",
"email": "studio@nova.io",
"phone": null,
"information": "Creative agency",
"participant_type": "provider",
"agreement_status": "pending",
"realisation_status": "not_started",
"participantType": "provider",
"owner": false
},
{
"id": "23c44f2e-865e-4c2f-8f85-2d3c5d2a9e11",
"user_id": null,
"fullname": "DShare Arbitration Desk",
"email": "panel@paycifi.com",
"phone": null,
"information": null,
"participant_type": "arbitrator",
"agreement_status": "pending",
"realisation_status": null,
"participantType": "arbitrator",
"owner": false
}
],
"agreementItems": [
{
"id": "agreement-name",
"description": "Design Sprint Retainer",
"quantity": 0,
"unitPrice": 0,
"fees": 0,
"participantId": "",
"isAgreementName": true
},
{
"id": "9c442ff5-97ad-43c4-a11d-53aa9b97519e",
"description": "Sprint fee",
"quantity": 4,
"unitPrice": 3000,
"fees": 0,
"participantId": "92a4b2b6-45f5-4501-8e71-0d371cbb9011",
"providerStatus": "pending",
"payerStatus": "pending"
}
],
"arbitrationSettings": {
"id": "23c44f2e-865e-4c2f-8f85-2d3c5d2a9e11",
"name": "DShare Arbitration Desk",
"email": "panel@paycifi.com",
"phone": null,
"additionalInfo": null,
"walletAddress": "0x5555...9999"
},
"blockchain": {
"rpcUrl": "https://polygon.rpc.paycifi.com",
"contractAddress": "0xabc123...789",
"tokenAddress": "0xdef456...321",
"createdAtBlock": 53288123
},
"blockchainAgreement": {
"agreementId": "0x646462...",
"payer": "0x1111...",
"provider": "0x2222...",
"amount": "12000000000",
"state": "Pending",
"unlockFundsTxHash": null
}
}
Response Handling¶
- 404 vs 409:
404 agreement-not-foundindicates an invalid ID;409 agreement-missing-contract-addressmeans the record exists but lacks an on-chain contract, so blockchain data cannot be fetched. - 500 errors: Treat
agreement-detail-retrieval-controller-errororblockchainAgreement-retrieval-controller-erroras transient server failures and prompt the user to retry. - State awareness: Use
agreementInfo.status, item statuses, and participantagreement_statusto determine whether to show funding, acceptance, realization, or arbitration actions. - Next actions: Combine this response with role-based permissions in your client. For example, only a payer participant with
owner: trueshould see the "Fund" action, which is executed by calling the DShare smart contract from a wallet that signs transactions on-chain; providers should act based on theiragreement_statusand item statuses.
Error Codes¶
| HTTP | errorCode | Description |
|---|---|---|
| 400 | missing-agreementId |
Path parameter was omitted. |
| 404 | agreement-not-found |
No agreement matches the provided ID. |
| 409 | agreement-missing-contract-address |
Agreement exists but has no contract address, so details cannot be completed. |
| 500 | agreement-detail-retrieval-controller-error |
Failure while reading agreement data from the database. |
| 500 | blockchainAgreement-retrieval-controller-error |
Failure while fetching the on-chain snapshot. |
Related Endpoints¶
GET /api/v1/agreements/user/:userId— retrieve the list before drilling into details.PATCH /api/v1/agreements/participants/:participantId/status— accept/decline an agreement after reviewing details.POST /api/v1/agreements/:agreementId/arbitration— request arbitration if the detail view shows a dispute scenario.
Next Step: Escrow Protocol¶
At this point, agreement behavior is no longer driven by REST APIs.
Fund movements, validation outcomes, arbitration, refunds, and completion are governed entirely by the DShare on-chain escrow protocol.
To understand how the agreement actually progresses and how funds move, continue with the protocol documentation.