Skip to content

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 populateUser middleware. 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: agreementId MUST be a valid UUID referencing an existing agreement with an on-chain contract address.

Client Responsibilities

  • Provide the agreementId path 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

  1. Client request: GET /api/v1/agreements/:agreementId with Authorization: Bearer <token>.
  2. Backend validation: The controller checks that agreementId exists. If missing, it returns 400 missing-agreementId.
  3. Data aggregation: AgreementsService.fetchAgreementById gathers:
  4. Agreement record + currency, fee strategy, totals, status, deadlines, RPC/network references, arbitrator status.
  5. Participants (payer, providers, arbitrator, contributor roles) including emails, phone numbers, agreement_status, realisation_status, and owner flag.
  6. Items (prefixed with an "agreement-name" pseudo-item) with provider/payer item statuses, fees, and assignments.
  7. Arbitration settings (arbitrator profile) and blockchain metadata (rpcUrl, contractAddress, tokenAddress, createdAtBlock).
  8. Blockchain enrichment: The controller requires a contract address; if absent, it returns 409 agreement-missing-contract-address. Otherwise it calls BlockchainService.getAgreement and attaches cached unlock transaction info (if any) under blockchainAgreement.unlockFundsTxHash.
  9. Response: A consolidated object containing participants, agreementInfo, agreementItems, arbitrationSettings, blockchain, agreementId, and blockchainAgreement (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-found indicates an invalid ID; 409 agreement-missing-contract-address means the record exists but lacks an on-chain contract, so blockchain data cannot be fetched.
  • 500 errors: Treat agreement-detail-retrieval-controller-error or blockchainAgreement-retrieval-controller-error as transient server failures and prompt the user to retry.
  • State awareness: Use agreementInfo.status, item statuses, and participant agreement_status to 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: true should 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 their agreement_status and 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.
  • 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.