PERSUIT is the leading legal procurement platform — enabling legal teams to manage outside counsel requests, evaluate proposals, and gain insights across their panel spend. Using the PERSUIT API, you can integrate PERSUIT data into your internal tools, reporting pipelines, and identity management systems.
PERSUIT APIs use the REST architecture, are defined using the OpenAPI specification, and use standard HTTP response codes and verbs. All APIs accept and return JSON and are secured with OAuth 2.0 authentication.
Contact us to request API access and get started with your integration.
Once you have requested an API key, our team will respond shortly with your credentials. In the meantime, we encourage your technical team to review the available endpoints and authentication requirements documented below to begin planning your integration. If you have any questions during this process, please do not hesitate to contact us.
| Section | Description |
|---|---|
| Authentication | Obtain an OAuth 2.0 access token using client credentials to authenticate API requests. |
| RFP | Search and retrieve requests (RFPs), selected proposals, and associated metadata. |
| REPORTING | Access flattened, analytics-ready data across requests, invites, proposals, scorecards, questions, answers, and tracking fields. |
| SCIM V2 - Users & Roles | Manage users and roles via the SCIM v2.0 standard for identity provider synchronization. |
| Handling API Errors | Learn about standard HTTP response codes, error formats, and how to resolve common issues. |
| Rate Limiting | Understand API rate limits, response headers, and recommended retry strategies. |
The PERSUIT API uses OAuth 2.0 client credentials to authenticate requests. All API endpoints require a valid Bearer token passed in the Authorization header.
Send a POST request to the token endpoint with your client credentials:
POST /api/oauth/token Content-Type: application/x-www-form-urlencoded Authorization: Basic <base64(: )> { "grant_type": "client_credentials" }
Sample response:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6...",
"token_type": "Bearer",
"expires_in": 3600
}Include the token as a Bearer token in the Authorization header of every request:
GET /api/v3/rfps Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6... Content-Type: application/json
Provides ability to search and retrieve data related to PERSUIT requests, selected proposals and associated metadata.
Ideal for integrations which require real-time data.
Get a non-Rate Review Pro RFP by the exact PERSUIT ID. Returns 404 if RFP does not exist or is not accessible to the user. Only non-Rate Review Pro RFPs belonging to your organisation are accessible via this API.
| persuitId required | string Example: REQ-123456 REQUIRED: the PERSUIT ID of the RFP being requested. |
| id required | string ID of the RFP |
| persuitId required | string PERSUIT ID of the RFP |
| title required | string Title of the RFP |
| status required | string (RfpStatusType) Enum: "DRAFT" "OPEN_TO_PROPOSALS" "EVALUATING" "AUCTION_IN_PROGRESS" "COMPLETED" "WITHDRAWN" Status of the RFP |
| reverseAuction required | boolean Denotes whether this RFP is using Reverse Auction |
| matterReference required | string Matter reference of the RFP specified in the tracking section by the client user |
required | object (Pricing) Pricing details of an RFP |
required | Array of objects (InvitedFirm) Invited Firms for this RFP |
| requestedBy required | string Name of the requester of the RFP (free text value provided by the client user) |
required | object (User) Details of a Persuit User |
| publishedAt | string <date-time> Date-Time when the RFP was published. Format: ISO 8601 in UTC. "example": "2010-01-01T12:34:56Z" |
| createdAt required | string <date-time> Date-Time when the RFP was created. Format: ISO 8601 in UTC. "example": "2010-01-01T12:34:56Z" |
| updatedAt required | string <date-time> Date-Time when the RFP was last updated Format: ISO 8601 in UTC. "example": "2010-01-01T12:34:56Z" |
required | Array of objects (Access) User access details of the RFP |
{- "id": "string",
- "persuitId": "string",
- "title": "string",
- "status": "DRAFT",
- "reverseAuction": true,
- "matterReference": "string",
- "pricing": {
- "description": "string",
- "currency": "string",
- "requestTotalPrice": true,
- "pricingModel": "NO_PREFERENCE",
- "allowOtherPricingModels": true,
- "items": [
- {
- "id": "string",
- "title": "string",
- "type": "PRICING_ITEM",
- "description": "string",
- "pricingModel": "NO_PREFERENCE",
- "subItems": [
- {
- "id": "string",
- "title": "string",
- "pricingModel": "NO_PREFERENCE"
}
], - "rateCard": {
- "rates": [
- {
- "id": "string",
- "title": "string"
}
], - "allowFirmsToAddEntries": true
}
}
]
}, - "invitedFirms": [
- {
- "id": "string",
- "status": "INVITED",
- "statusAt": "2019-08-24T14:15:22Z",
- "firm": {
- "id": "string",
- "name": "string"
}, - "memberAccess": [
- {
- "accessType": "EDIT",
- "user": {
- "id": "string",
- "orgId": "string",
- "firstName": "string",
- "lastName": "string",
- "email": "string",
- "disabled": true
}, - "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}
]
}
], - "requestedBy": "string",
- "createdBy": {
- "id": "string",
- "orgId": "string",
- "firstName": "string",
- "lastName": "string",
- "email": "string",
- "disabled": true
}, - "publishedAt": "2019-08-24T14:15:22Z",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "access": [
- {
- "accessType": "EDIT",
- "user": {
- "id": "string",
- "orgId": "string",
- "firstName": "string",
- "lastName": "string",
- "email": "string",
- "disabled": true
}, - "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}
]
}Get all non-Rate Review Pro RFPs. If no criteria/parameter is provided, then returns all RFPs. Only non rate review RFPs belonging to your organisation are accessible via this API.
| persuitId | string Example: persuitId=REQ-123 OPTIONAL: Only return RFPs that include this string in the PERSUIT ID. |
| title | string Example: title=my rfp title OPTIONAL: Only return RFPs that include this string in the RFP title. |
| requesterName | string Example: requesterName=John Doe OPTIONAL: Only return RFPs that include this string in the requester's name. |
| matterReference | string Example: matterReference=2022-123456 OPTIONAL: Only return RFPs that include this string in the matter reference. |
| id required | string ID of the RFP |
| persuitId required | string PERSUIT ID of the RFP |
| title required | string Title of the RFP |
| status required | string (RfpStatusType) Enum: "DRAFT" "OPEN_TO_PROPOSALS" "EVALUATING" "AUCTION_IN_PROGRESS" "COMPLETED" "WITHDRAWN" Status of the RFP |
| reverseAuction required | boolean Denotes whether this RFP is using Reverse Auction |
| matterReference required | string Matter reference of the RFP specified in the tracking section by the client user |
required | object (Pricing) Pricing details of an RFP |
required | Array of objects (InvitedFirm) Invited Firms for this RFP |
| requestedBy required | string Name of the requester of the RFP (free text value provided by the client user) |
required | object (User) Details of a Persuit User |
| publishedAt | string <date-time> Date-Time when the RFP was published. Format: ISO 8601 in UTC. "example": "2010-01-01T12:34:56Z" |
| createdAt required | string <date-time> Date-Time when the RFP was created. Format: ISO 8601 in UTC. "example": "2010-01-01T12:34:56Z" |
| updatedAt required | string <date-time> Date-Time when the RFP was last updated Format: ISO 8601 in UTC. "example": "2010-01-01T12:34:56Z" |
required | Array of objects (Access) User access details of the RFP |
[- {
- "id": "string",
- "persuitId": "string",
- "title": "string",
- "status": "DRAFT",
- "reverseAuction": true,
- "matterReference": "string",
- "pricing": {
- "description": "string",
- "currency": "string",
- "requestTotalPrice": true,
- "pricingModel": "NO_PREFERENCE",
- "allowOtherPricingModels": true,
- "items": [
- {
- "id": "string",
- "title": "string",
- "type": "PRICING_ITEM",
- "description": "string",
- "pricingModel": "NO_PREFERENCE",
- "subItems": [
- {
- "id": "string",
- "title": "string",
- "pricingModel": "NO_PREFERENCE"
}
], - "rateCard": {
- "rates": [
- {
- "id": "string",
- "title": "string"
}
], - "allowFirmsToAddEntries": true
}
}
]
}, - "invitedFirms": [
- {
- "id": "string",
- "status": "INVITED",
- "statusAt": "2019-08-24T14:15:22Z",
- "firm": {
- "id": "string",
- "name": "string"
}, - "memberAccess": [
- {
- "accessType": "EDIT",
- "user": {
- "id": "string",
- "orgId": "string",
- "firstName": "string",
- "lastName": "string",
- "email": "string",
- "disabled": true
}, - "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}
]
}
], - "requestedBy": "string",
- "createdBy": {
- "id": "string",
- "orgId": "string",
- "firstName": "string",
- "lastName": "string",
- "email": "string",
- "disabled": true
}, - "publishedAt": "2019-08-24T14:15:22Z",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "access": [
- {
- "accessType": "EDIT",
- "user": {
- "id": "string",
- "orgId": "string",
- "firstName": "string",
- "lastName": "string",
- "email": "string",
- "disabled": true
}, - "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}
]
}
]Get all selected-proposals for the RFP using the exact PERSUIT ID for the RFP. Returns 404 if RFP does not exist or is not accessible to the user. Only selected proposals for non-Rate Review Pro RFPs belonging to your organisation are accessible via this API.
| persuitId required | string Example: REQ-123456 REQUIRED: the PERSUIT ID of the RFP being requested |
| id required | string The ID of the proposal |
| rfpId required | string The ID of the corresponding RFP |
required | object (Org) Organisation details |
| subject required | string The subject or title of the proposal |
| summary required | string The summary of the proposal |
| status required | string (RfpProposalStatusType) Enum: "DRAFT" "EDIT" "FINALIZED" "SELECTED" "ELIMINATED" "WITHDRAWN" "COMPETITOR" "EXAMPLE" "DRAFT_REVISION" "DRAFT_REVISION_DISCARDED" "UNDER_REVISION" "REVISED" "SENT" "VIEW" Status type of the Proposal |
| selectedOn | string <date-time> The Date on which the Proposal was first Selected |
required | object (ProposalPricing) Pricing details of the Proposal |
required | object (User) Details of a Persuit User |
| createdAt required | string <date-time> Date-Time when the proposal was created. Format: ISO 8601 in UTC. "example": "2010-01-01T12:34:56Z" |
| updatedAt required | string <date-time> Date-Time when the proposal was last updated Format: ISO 8601 in UTC. "example": "2010-01-01T12:34:56Z" |
[- {
- "id": "string",
- "rfpId": "string",
- "firm": {
- "id": "string",
- "name": "string"
}, - "subject": "string",
- "summary": "string",
- "status": "DRAFT",
- "selectedOn": "2019-08-24T14:15:22Z",
- "pricing": {
- "totalPriceModel": "NO_PREFERENCE",
- "priceType": "TOTAL_PRICE",
- "totalFee": 0.1,
- "comparisonValue": 0.1,
- "averageRate": 0.1,
- "items": [
- {
- "id": "string",
- "pricingItemId": "string",
- "excludedFromScope": true,
- "description": "string",
- "pricingModel": "NO_PREFERENCE",
- "fee": 0.1,
- "percentage": 0.1,
- "hours": 0.1,
- "proposalPricingSubItems": [
- {
- "title": "string",
- "type": "ProposalPricingFeeSubItem",
- "pricingModel": {
- "length": 0.1,
- "property1": "string",
- "property2": "string"
}, - "fee": 0.1,
- "hours": 0.1
}
], - "hourlyRate": 0.1,
- "rateCard": [
- {
- "id": "string",
- "pricingRateCardItemId": "string",
- "name": "string",
- "rate": 0.1,
- "addedByFirm": true
}
]
}
]
}, - "createdBy": {
- "id": "string",
- "orgId": "string",
- "firstName": "string",
- "lastName": "string",
- "email": "string",
- "disabled": true
}, - "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}
]Provides access to reporting-oriented data including requests, invites, proposals, scores, questions, tracking fields etc.
Each endpoint provides flatly structured response containing ID fields (i.e. persuitId, firmId, inviteId, proposalId etc.) which can be used to connect or reference data provided by the other reporting endpoints.
Data is not guaranteed to be real time, updates may take up to 10 minutes to be available via these endpoints.
Best suited for analytics, dashboards, and reporting workflows which require data to be structured flatly.
For custom Power BI connector, please contact us.
Get all RFP invite summaries Only invites for non-Rate Review Pro RFPs belonging to your organisation are accessible via this API
| persuitId | string Example: persuitId=REQ-123456 OPTIONAL: Only return invites for this RFP PERSUIT ID |
| includeRateReviewPro | boolean OPTIONAL: Include Rate Review Pro requests in the response. |
| includeDrafts | boolean OPTIONAL: Include draft RFPs in the response. |
| userEmail | string OPTIONAL: Filter by user email to return only invites for RFPs accessible to that user. |
| inviteId required | string ID of the invite |
| persuitId required | string Persuit Id of the corresponding RFP |
| firmId required | string or null ID of the firm |
| firmName required | string or null Name of the firm |
| invitedAt required | string or null <date-time> Date-Time when the invite was sent Format: ISO 8601 in UTC. "example": "2010-01-01T12:34:56Z" |
| inviteStatus required | string or null Enum: "INVITED" "VIEWED_REQUEST" "UNABLE_TO_CLEAR_CONFLICT" "CLEARED_CONFLICT" "UNABLE_TO_PARTICIPATE" "AGREED_TO_PARTICIPATE" "SUBMITTED_PROPOSAL" "UNSUCCESSFUL" "SELECTED" Status of the invite |
| rfpViewed required | boolean Denotes (True/False) whether the law firm has viewed the RFP |
| conflictCheckCleared required | boolean or null Denotes (True/False) whether the law firm cleared conflict check (null if the corresponding RFP does not require conflict check) |
| firmAgreedToParticipate required | boolean or null Denotes (True/False) whether the law firm has agreed to participate (null if the law firm has not answered yet) |
| requestReopenedForFirm required | boolean Denotes (True/False) whether the request was re-opened for the law firm |
| includedInAnalytics required | boolean Denotes if the corresponding request is included in analytics (e.g. insights) |
[- {
- "inviteId": "string",
- "persuitId": "string",
- "firmId": "string",
- "firmName": "string",
- "invitedAt": "2019-08-24T14:15:22Z",
- "inviteStatus": "INVITED",
- "rfpViewed": true,
- "conflictCheckCleared": true,
- "firmAgreedToParticipate": true,
- "requestReopenedForFirm": true,
- "includedInAnalytics": true
}
]Get all proposal scorecard category and subcategory score summaries. Only scorecard category and subcategory scores for proposals submitted for non-Rate Review Pro RFPs belonging to your organisation are accessible via this API.
| persuitId | string Example: persuitId=REQ-123456 OPTIONAL: Only return proposal scorecard category and subcategory scores for this RFP PERSUIT ID |
| includeRateReviewPro | boolean OPTIONAL: Include Rate Review Pro requests in the response. |
| userEmail | string OPTIONAL: Filter by user email to return only proposal scorecards for RFPs accessible to that user. |
| persuitId required | string Persuit ID of the corresponding RFP |
| proposalId required | string The ID of the proposal |
| firmId required | string ID of the firm submitting this proposal |
| firmName required | string Name of the firm submitting this proposal |
| scorecardCategoryId required | string The ID of the scorecard category |
| scorecardCategoryName required | string The name of the scorecard category |
| scorecardCategoryScorePercentage required | number <double> The average percentage score for this scorecard category provided by the client users. Decimal number between 0 and 100 rounded 2 decimal places. "example": 95.99 |
| scorecardCategoryWeightPercentage required | number <double> The percentage weight of this scorecard category provided at the request level. Decimal number between 0 and 100 rounded 2 decimal places. "example": 95.99 |
| numberOfSubcategories required | number <double> The number of scorecard subcategories under this scorecard category |
| scorecardSubcategoryId required | string or null The ID of the scorecard subcategory (null if no scorecard subcategory exists for this scorecard category) |
| scorecardSubcategoryName required | string or null The name of the scorecard subcategory (null if no scorecard subcategory exists for this scorecard category) |
| scorecardSubcategoryScorePercentage required | number or null <double> The average percentage score for this scorecard subcategory provided by the client users. Decimal number between 0 and 100 rounded 2 decimal places. "example": 95.99 (null if no scorecard subcategory exists for this scorecard category) |
| includedInAnalytics required | boolean Denotes if the corresponding request is included in analytics (e.g. insights) |
[- {
- "persuitId": "string",
- "proposalId": "string",
- "firmId": "string",
- "firmName": "string",
- "scorecardCategoryId": "string",
- "scorecardCategoryName": "string",
- "scorecardCategoryScorePercentage": 0.1,
- "scorecardCategoryWeightPercentage": 0.1,
- "numberOfSubcategories": 0.1,
- "scorecardSubcategoryId": "string",
- "scorecardSubcategoryName": "string",
- "scorecardSubcategoryScorePercentage": 0.1,
- "includedInAnalytics": true
}
]Get all proposal summaries. Only proposals submitted for non-Rate Review Pro RFPs belonging to your organisation are accessible via this API.
| persuitId | string Example: persuitId=REQ-123456 OPTIONAL: Only return proposals for this RFP PERSUIT ID. |
| targetCurrency | string Example: targetCurrency=EUR OPTIONAL: Return all prices in this currency (as per closing exchange rates on proposal due date). Accepts 3 character ISO currency code. |
| includeRateReviewPro | boolean OPTIONAL: Include Rate Review Pro requests in the response. |
| includeAllPrices | boolean OPTIONAL: Include all prices in the response (even for requests where totalPriceRequired is false). |
| userEmail | string OPTIONAL: Filter by user email to return only proposals for RFPs accessible to that user. |
| id | string Deprecated The ID of the proposal |
| proposalId required | string The ID of the proposal |
| rfpId | string Deprecated The ID of the corresponding RFP |
| persuitId required | string Persuit Id of the corresponding RFP |
| rfpPersuitId | string or null Deprecated Persuit Id of the corresponding RFP |
| inviteId required | string or null The ID of the corresponding invitation to the firm |
| rfpTitle required | string or null Title of the RFP |
| rfpRequestedBy required | string or null Name of the requester of the RFP (free text value provided by the client user) |
| rfpSentAt required | string or null <date-time> Date-Time when the RFP was sent. Format: ISO 8601 in UTC. "example": "2010-01-01T12:34:56Z" |
| firmId required | string or null ID of the firm submitting this proposal |
| firmName required | string or null Name of the firm submitting this proposal |
| submittedAt required | string or null <date-time> Date-Time when this proposal was first submitted. Format: ISO 8601 in UTC. "example": "2010-01-01T12:34:56Z" |
| status | string (RfpProposalStatusType) Enum: "DRAFT" "EDIT" "FINALIZED" "SELECTED" "ELIMINATED" "WITHDRAWN" "COMPETITOR" "EXAMPLE" "DRAFT_REVISION" "DRAFT_REVISION_DISCARDED" "UNDER_REVISION" "REVISED" "SENT" "VIEW" Status type of the Proposal |
| proposalStatus required | string (RfpProposalStatusType) Enum: "DRAFT" "EDIT" "FINALIZED" "SELECTED" "ELIMINATED" "WITHDRAWN" "COMPETITOR" "EXAMPLE" "DRAFT_REVISION" "DRAFT_REVISION_DISCARDED" "UNDER_REVISION" "REVISED" "SENT" "VIEW" Status type of the Proposal |
| conflictCleared | boolean or null Deprecated Denotes if the firm cleared conflict check (null if the corresponding RFP does not require conflict check) |
| conflictCheckCleared required | boolean or null Denotes if the law firm has cleared conflict check (null if the corresponding RFP does not require conflict check) |
| selected required | boolean Denotes whether this proposal was selected by the client |
| selectedAt required | string or null <date-time> Date-Time when this proposal was first selected (null if proposal has not been selected). Format: ISO 8601 in UTC. "example": "2010-01-01T12:34:56Z" |
| rfpRequestTotalPrice required | boolean Denotes if the "Request Total Price" checkbox is checked on the RFP |
| totalPriceModel required | string or null Enum: "NO_PREFERENCE" "CAPPED_FEE" "COLLARED_FEE" "CONTINGENCY_FEE" "CONTINGENCY_PERCENTAGE" "DISCOUNT_PERCENTAGE" "FIXED_FEE" "SUCCESS_FEE" "BUDGETING_ESTIMATE" "HOURLY_RATE" "RATE_CARD" "OTHER" "NO_CHARGE" "NOT_APPLICABLE" Total Price Model of this proposal (null if rfpRequestTotalPrice is/was FALSE when the proposal was created) |
| currency required | string or null The currency used for the prices in this API response. (3 character ISO currency code) |
| originalCurrency required | string or null The original currency used for the request and proposals in PERSUIT. (3 character ISO currency code) |
| startingTotalPrice required | number or null <double> Starting total price of this proposal (null if rfpRequestTotalPrice is/was FALSE when the proposal was created) |
| finalTotalPrice required | number or null <double> Final total price of this proposal (null if rfpRequestTotalPrice is/was FALSE when the proposal was created) |
| priceAtAuctionStart required | number or null <double> Example: "10000" Price at the start of the auction. |
| priceAtAuctionEnd required | number or null <double> Example: "8000" Price at the end of the auction. |
| priceChangeDuringAuction required | number or null <double> Example: "-2000" Price change during the auction. |
| priceChangeDuringAuctionPercentage required | number or null <double> Example: "-20.05" Percentage of price change during the auction. |
| includeStandardDiversityQuestions required | boolean or null Denotes whether the corresponding RFP requires standard diveristy questions answered |
| diverseLeadOrFirstOrSecondChair required | boolean or null Denotes whether the lead lawyer or (in case of litigation) first or second chair is diverse. null if includeStandardDiversityQuestions is false or the law firm has marked this as NOT_APPLICABLE |
| diverseLeadOrFirstOrSecondChairNotApplicable required | boolean or null Denotes whether the law firm has marked diverseLeadOrFirstOrSecondChair as NOT_APPLICABLE null if includeStandardDiversityQuestions is false |
| diverseLeadOrFirstOrSecondChairLawFirmComment required | string or null Comment provided by law firm for the question diverseLeadOrFirstOrSecondChair null if includeStandardDiversityQuestions is false |
| percentageOfWorkCompletedByDiverseLawyers required | number or null <double> Denotes the percentage value of the total scope of work completed by diverse lawyers null if includeStandardDiversityQuestions is false or the law firm has marked this as NOT_APPLICABLE |
| percentageOfWorkCompletedByDiverseLawyersNotApplicable required | boolean or null Denotes whether the law firm has marked percentageOfWorkCompletedByDiverseLawyers as NOT_APPLICABLE null if includeStandardDiversityQuestions is false |
| percentageOfWorkCompletedByDiverseLawyersLawFirmComment required | string or null Comment provided by law firm for the question percentageOfWorkCompletedByDiverseLawyers null if includeStandardDiversityQuestions is false |
| percentageOfOriginationCreditToDiverseLawyers required | number or null <double> Denotes the percentage value of the origination credit (business generation) awarded to diverse lawyers null if includeStandardDiversityQuestions is false or the law firm has marked this as NOT_APPLICABLE |
| percentageOfOriginationCreditToDiverseLawyersNotApplicable required | boolean or null Denotes whether the law firm has marked percentageOfOriginationCreditToDiverseLawyers as NOT_APPLICABLE null if includeStandardDiversityQuestions is false |
| percentageOfOriginationCreditToDiverseLawyersLawFirmComment required | string or null Comment provided by law firm for the question percentageOfOriginationCreditToDiverseLawyers null if includeStandardDiversityQuestions is false |
| firmMANSFIELDRuleCertified required | boolean or null Denotes if the firm is MANSFIELD rule certified |
| firmMWBECertified required | boolean or null Denotes if the firm is MWBE (Minority or Women Owned Business Enterprise) certified |
| firmNAMWOLFMember required | boolean or null Denotes if the firm is a NAMWOLF member |
| averageWeightedScore required | number or null <double> The average percentage of the weighted scores for this proposal provided by the client users. Decimal number between 0 and 100 rounded 2 decimal places. "example": 95.99 |
| includedInAnalytics required | boolean Denotes if the corresponding request is included in analytics (e.g. insights) |
[- {
- "id": "string",
- "proposalId": "string",
- "rfpId": "string",
- "persuitId": "string",
- "rfpPersuitId": "string",
- "inviteId": "string",
- "rfpTitle": "string",
- "rfpRequestedBy": "string",
- "rfpSentAt": "2019-08-24T14:15:22Z",
- "firmId": "string",
- "firmName": "string",
- "submittedAt": "2019-08-24T14:15:22Z",
- "status": "DRAFT",
- "proposalStatus": "DRAFT",
- "conflictCleared": true,
- "conflictCheckCleared": true,
- "selected": true,
- "selectedAt": "2019-08-24T14:15:22Z",
- "rfpRequestTotalPrice": true,
- "totalPriceModel": "NO_PREFERENCE",
- "currency": "string",
- "originalCurrency": "string",
- "startingTotalPrice": 0.1,
- "finalTotalPrice": 0.1,
- "priceAtAuctionStart": 10000,
- "priceAtAuctionEnd": 8000,
- "priceChangeDuringAuction": -2000,
- "priceChangeDuringAuctionPercentage": -20.05,
- "includeStandardDiversityQuestions": true,
- "diverseLeadOrFirstOrSecondChair": true,
- "diverseLeadOrFirstOrSecondChairNotApplicable": true,
- "diverseLeadOrFirstOrSecondChairLawFirmComment": "string",
- "percentageOfWorkCompletedByDiverseLawyers": 0.1,
- "percentageOfWorkCompletedByDiverseLawyersNotApplicable": true,
- "percentageOfWorkCompletedByDiverseLawyersLawFirmComment": "string",
- "percentageOfOriginationCreditToDiverseLawyers": 0.1,
- "percentageOfOriginationCreditToDiverseLawyersNotApplicable": true,
- "percentageOfOriginationCreditToDiverseLawyersLawFirmComment": "string",
- "firmMANSFIELDRuleCertified": true,
- "firmMWBECertified": true,
- "firmNAMWOLFMember": true,
- "averageWeightedScore": 0.1,
- "includedInAnalytics": true
}
]Get all RFP summaries. Only non-Rate Review Pro RFPs belonging to your organisation are accessible via this API.
| persuitId | string Example: persuitId=REQ-123456 OPTIONAL: Only return the matching RFP record. |
| targetCurrency | string Example: targetCurrency=EUR OPTIONAL: Return all prices in this currency (as per closing exchange rates on proposal due date). Accepts 3 character ISO currency code. |
| includeRateReviewPro | boolean OPTIONAL: Include Rate Review Pro requests in the response. |
| includeAllPrices | boolean OPTIONAL: Include all prices in the response (even for requests where totalPriceRequired is false). |
| includeDrafts | boolean OPTIONAL: Include draft RFPs in the response. |
| userEmail | string OPTIONAL: Filter by user email to return only RFPs accessible to that user. |
| id | string Deprecated ID of the RFP |
| persuitId required | string Persuit Id of the RFP |
| requestUseCase required | string or null Enum: "RATE_REVIEW_PRO" "SINGLE_MATTER_OR_PROJECT_RFP" "PORTFOLIO_OR_MULTI_MATTER_RFP" "HOURLY_RATE_NEGOTIATION" "PANEL_OR_PREFERRED_FIRM_VENDOR_RFP" "SECONDMENT_OR_TEMPORARY_STAFFING" "NEGOTIATE_AFA_ON_EXISTING_MATTER" "RFI_OR_SURVEY" Denotes the use case of this request |
| title required | string Title of the RFP |
| matterReference required | string Matter reference of the RFP specified in the tracking section by the client user |
| status | string (RfpStatusType) Enum: "DRAFT" "OPEN_TO_PROPOSALS" "EVALUATING" "AUCTION_IN_PROGRESS" "COMPLETED" "WITHDRAWN" Status of the RFP |
| rfpStatus required | string (RfpStatusType) Enum: "DRAFT" "OPEN_TO_PROPOSALS" "EVALUATING" "AUCTION_IN_PROGRESS" "COMPLETED" "WITHDRAWN" Status of the RFP |
| requestedBy required | string Name of the requester of the RFP (free text value provided by the client user) |
| createdByUserId required | string or null ID of the user who created the RFP |
| createdByUserName required | string or null Full name of the user who created the RFP |
| createdByUserEmail required | string or null Primary email of the user who created the RFP |
| createdAt required | string or null <date-time> Date-Time when the RFP was created Format: ISO 8601 in UTC. "example": "2010-01-01T12:34:56Z" |
| updatedAt required | string or null <date-time> Date-Time when the RFP was last updated Format: ISO 8601 in UTC. "example": "2010-01-01T12:34:56Z" |
| sentAt required | string or null <date-time> Date-Time when the RFP was sent (null if RFP was not sent). Format: ISO 8601 in UTC. "example": "2010-01-01T12:34:56Z" |
| completedAt required | string or null <date-time> Date-Time when the RFP was marked completed. Format: ISO 8601 in UTC. "example": "2010-01-01T12:34:56Z" |
| proposalsDueDate required | string or null <date-time> Date-Time when proposals are due by. Format: ISO 8601 in UTC. "example": "2010-01-01T12:34:56Z" |
| reverseAuction required | boolean Denotes whether this RFP is using Reverse Auction |
| reverseAuctionStartDate required | string or null <date-time> Date-Time when the reverse auction will start (null if RFP is not using reverse auction). Format: ISO 8601 in UTC. "example": "2010-01-01T12:34:56Z" |
| reverseAuctionEndDate required | string or null <date-time> Date-Time when the reverse auction will end. (null if RFP is not using reverse auction). Format: ISO 8601 in UTC. "example": "2010-01-01T12:34:56Z" |
| reverseAuctionVisibilityType required | string or null Enum: "PRICE_RANKING_ONLY" "PRICE_RANKING_AND_LOWEST_BID" "PRICE_RANKING_AND_ALL_BIDS" "PHASE_RANKING_AND_LOWEST_PHASE_PRICE" Reverse auction price and rank visibility type for firms (null if RFP is not using reverse auction) |
| currency required | string or null The currency used for the prices in this API response. (3 character ISO currency code) |
| originalCurrency required | string or null The original currency used for the request and proposals in PERSUIT. (3 character ISO currency code) |
| requestTotalPrice required | boolean Denotes if the "Request Total Price" checkbox is checked or not |
| isTotalComparisonRequest required | boolean Denotes if the request is a total comparison request |
| hasPrice required | boolean Denotes if the request or any of the proposals has a non-zero price |
| isAFA required | boolean Denotes if the request is AFA (Alternative Fee Arrangement). |
| pricingModel required | string or null Enum: "NO_PREFERENCE" "CAPPED_FEE" "COLLARED_FEE" "CONTINGENCY_FEE" "CONTINGENCY_PERCENTAGE" "DISCOUNT_PERCENTAGE" "FIXED_FEE" "SUCCESS_FEE" "BUDGETING_ESTIMATE" "HOURLY_RATE" "RATE_CARD" "OTHER" "NO_CHARGE" "NOT_APPLICABLE" Pricing Model of the RFP (null if requestTotalPrice is FALSE) |
| numberOfQuestions required | number <double> Total number of questions asked by the Client to firms |
| numberOfRequiredQuestions required | number <double> Total number of Required questions asked by the Client to firms |
| conflictCheckRequired required | boolean Is conflict check / T&Cs / NDA required |
| numberOfInvitedFirms required | number <double> Total number of invited firms |
| numberOfConflictClearedFirms required | number or null <double> Total number of firms which cleared conflict (null if conflict check is not required) |
| numberOfParticipatingFirms required | number <double> Total number of firms which agreed to participate |
| numberOfFirmsWithProposals required | number <double> Total number of firms which submitted one or more proposals (excluding draft proposals) |
| numberOfSelectedFirms required | number <double> Total number of firms selected |
| selectedFirmId required | string or null ID of the selected firm (null if zero or multiple firms have been selected) |
| selectedFirmName required | string or null Name of the selected firm (null if zero or multiple firms have been selected) |
| selectedAt required | string or null <date-time> Date-Time when the first proposal was selected. Format: ISO 8601 in UTC. "example": "2010-01-01T12:34:56Z" |
| numberOfProposals required | number <double> Total number of proposals submitted (excluding draft proposals) |
| numberOfSelectedProposals required | number <double> Total number of proposals selected |
| selectedProposalsAverageFinalTotalPrice required | number or null <double> The average of the final total prices of all selected proposals (null if no proposal has been selected OR requestTotalPrice is FALSE) |
| selectedProposalId required | string or null ID of the selected proposal (null if zero or multiple proposals have been selected) |
| lowestFinalTotalPrice required | number or null <double> Lowest final total price among submitted proposals (null if requestTotalPrice is FALSE) |
| highestStartingTotalPrice required | number or null <double> Highest starting total price among submitted proposals (null if requestTotalPrice is FALSE) |
| averageStartingTotalPrice required | number or null <double> Average starting total price of all submitted proposals (null if requestTotalPrice is FALSE) |
| averageStartingTotalPriceImpactedByOutlier required | boolean or null Denotes if the "averageStartingTotalPrice" is impacted due to at least one starting proposal being an outlier. (null if requestTotalPrice is FALSE) (Outlier is defined as being more than 2 standard deviations from the mean AND more than 300% above or 30% below the average) |
| averageFinalTotalPrice required | number or null <double> Average final total price of all submitted proposals (null if requestTotalPrice is FALSE) |
| averageFinalTotalPriceImpactedByOutlier required | boolean or null Denotes if the "averageFinalTotalPrice" is impacted due to at least one final proposal being an outlier. (null if requestTotalPrice is FALSE) (Outlier is defined as being more than 2 standard deviations from the mean AND more than 300% above or 30% below the average) |
| changeInAverageTotalPrice required | number or null <double> Difference between the average of final total prices and the average of starting total prices (null if requestTotalPrice is FALSE) e.g. X = the average of starting total prices Y = the average of final total prices changeInAverageTotalPrice = X - Y |
| changeInAverageTotalPricePercentage required | number or null <double> Percentage difference between the average of final total prices and the average of starting total prices. (null if requestTotalPrice is FALSE) e.g. X = the average of starting total prices Y = the average of final total prices changeInAverageTotalPricePercentage = (X - Y) * 100 / X |
| averageReverseAuctionStartTotalPrice required | number or null <double> Average total price of all submitted proposals at the time of reverse auction start This can be different from the average proposal starting amount as proposals can change between initial submission and auction start (null if requestTotalPrice is FALSE OR reverse auction is NOT used) |
| averageReverseAuctionStartTotalPriceImpactedByOutlier required | boolean or null Denotes if the "averageReverseAuctionStartTotalPrice" is impacted due to at least one proposal being an outlier at the time of reverse auction start. (null if requestTotalPrice is FALSE OR reverse auction is NOT used) (Outlier is defined as being more than 2 standard deviations from the mean AND more than 300% above or 30% below the average) |
| changeInAverageReverseAuctionTotalPricePercentage required | number or null <double> The average percentage decrease in total price during auctions, excluding Draft and Withdrawn requests. (null if reverse auction is NOT used). |
| savingsCalculationMethod required | string (SavingsCalculationMethodType) Enum: "RELATIVE_TO_AVERAGE_STARTING_TOTAL_PRICE" "RELATIVE_TO_HIGHEST_STARTING_TOTAL_PRICE" "WINNER_DELTA" "MEDIAN" Savings Calculation type |
| savingsOverride required | boolean Denotes if savings amount was overridden/adjusted by the client (only managers can override) |
| adjustedSavings required | number or null <double> Adjusted savings set/overridden by the client (null if savings is not overridden) |
| adjustedAgreedFee required | number or null <double> Adjusted agreed fee set/overridden by the client (null if savings is not overridden) |
| adjustedBaselineFee required | number or null <double> Adjusted baseline fee set/overridden by the client (null if savings is not overridden) |
| adjustedSavingsPercentage required | number or null <double> Adjusted savings percentage considering the adjustedSavings and adjustedBaselineFee (null if savings is not overridden) |
| adjustedSavingsDescription required | string or null Adjusted savings description provided by the client (null if savings is not overridden) |
| estimatedSavings required | number or null <double> Savings calculated using the Client’s Savings method and the selected proposal having the lowest final total price. If no proposal is accepted, then this is the value after subtracting the lowest final proposal from the average of all initial proposals. e.g. A = average of initial proposals B = lowest final proposal estimatedSavings = A - B |
| estimatedSavingsPercentage required | number or null <double> Savings percentage calculated using the Client’s selected Savings method. If no proposal is accepted, then this is the percentage value from dividing the difference between the average of all initial proposals and the average all final proposals by the average of all initial proposals. e.g. X = average of initial proposals Y = average of final proposals estimatedSavingsPercentage = (X - Y) * 100 / X |
| includedInAnalytics required | boolean Denotes if the corresponding request is included in analytics (e.g. insights) |
| groupId required | string ID of the PERSUIT group to which this RFP belongs |
| groupName required | string Name of the PERSUIT group to which this RFP belongs |
[- {
- "id": "string",
- "persuitId": "string",
- "requestUseCase": "RATE_REVIEW_PRO",
- "title": "string",
- "matterReference": "string",
- "status": "DRAFT",
- "rfpStatus": "DRAFT",
- "requestedBy": "string",
- "createdByUserId": "string",
- "createdByUserName": "string",
- "createdByUserEmail": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "sentAt": "2019-08-24T14:15:22Z",
- "completedAt": "2019-08-24T14:15:22Z",
- "proposalsDueDate": "2019-08-24T14:15:22Z",
- "reverseAuction": true,
- "reverseAuctionStartDate": "2019-08-24T14:15:22Z",
- "reverseAuctionEndDate": "2019-08-24T14:15:22Z",
- "reverseAuctionVisibilityType": "PRICE_RANKING_ONLY",
- "currency": "string",
- "originalCurrency": "string",
- "requestTotalPrice": true,
- "isTotalComparisonRequest": true,
- "hasPrice": true,
- "isAFA": true,
- "pricingModel": "NO_PREFERENCE",
- "numberOfQuestions": 0.1,
- "numberOfRequiredQuestions": 0.1,
- "conflictCheckRequired": true,
- "numberOfInvitedFirms": 0.1,
- "numberOfConflictClearedFirms": 0.1,
- "numberOfParticipatingFirms": 0.1,
- "numberOfFirmsWithProposals": 0.1,
- "numberOfSelectedFirms": 0.1,
- "selectedFirmId": "string",
- "selectedFirmName": "string",
- "selectedAt": "2019-08-24T14:15:22Z",
- "numberOfProposals": 0.1,
- "numberOfSelectedProposals": 0.1,
- "selectedProposalsAverageFinalTotalPrice": 0.1,
- "selectedProposalId": "string",
- "lowestFinalTotalPrice": 0.1,
- "highestStartingTotalPrice": 0.1,
- "averageStartingTotalPrice": 0.1,
- "averageStartingTotalPriceImpactedByOutlier": true,
- "averageFinalTotalPrice": 0.1,
- "averageFinalTotalPriceImpactedByOutlier": true,
- "changeInAverageTotalPrice": 0.1,
- "changeInAverageTotalPricePercentage": 0.1,
- "averageReverseAuctionStartTotalPrice": 0.1,
- "averageReverseAuctionStartTotalPriceImpactedByOutlier": true,
- "changeInAverageReverseAuctionTotalPricePercentage": 0.1,
- "savingsCalculationMethod": "RELATIVE_TO_AVERAGE_STARTING_TOTAL_PRICE",
- "savingsOverride": true,
- "adjustedSavings": 0.1,
- "adjustedAgreedFee": 0.1,
- "adjustedBaselineFee": 0.1,
- "adjustedSavingsPercentage": 0.1,
- "adjustedSavingsDescription": "string",
- "estimatedSavings": 0.1,
- "estimatedSavingsPercentage": 0.1,
- "includedInAnalytics": true,
- "groupId": "string",
- "groupName": "string"
}
]Get all RFP tracking summaries Only tracking fields for non-Rate Review Pro RFPs belonging to your organisation are accessible via this API
| persuitId | string Example: persuitId=REQ-123456 OPTIONAL: Only return tracking fields for this RFP PERSUIT ID |
| includeRateReviewPro | boolean OPTIONAL: Include Rate Review Pro requests in the response. |
| includeDrafts | boolean OPTIONAL: Include draft RFPs in the response. |
| userEmail | string OPTIONAL: Filter by user email to return only tracking summary for RFPs accessible to that user. |
| persuitId required | string Persuit Id of the corresponding RFP |
| trackingFieldId required | string ID of the tracking field |
| trackingFieldName required | string or null Name of the tracking field |
| trackingFieldType required | string or null Enum: "PLAIN_TEXT" "RICH_TEXT" "NUMERIC" "DATE" "HIERARCHY" "HIERARCHY_CSV" "HIERARCHY_SINGLE_SELECT" Type of the RFP tracking field |
| trackingFieldvalue required | string or null Value of the RFP tracking field |
| includedInAnalytics required | boolean Denotes if the corresponding request is included in analytics (e.g. insights) |
[- {
- "persuitId": "string",
- "trackingFieldId": "string",
- "trackingFieldName": "string",
- "trackingFieldType": "PLAIN_TEXT",
- "trackingFieldvalue": "string",
- "includedInAnalytics": true
}
]Get summary of all RFP questions and answers provided by firms. By default only questions and answers for non-Rate Review Pro RFPs belonging to your organisation are accessible via this API.
| persuitId | string Example: persuitId=REQ-123456 OPTIONAL: Only return questions and answers for this RFP PERSUIT ID |
| includeRateReviewPro | boolean OPTIONAL: Include Rate Review Pro requests in the response. |
| userEmail | string OPTIONAL: Filter by user email to return only proposal answers for RFPs accessible to that user. |
| persuitId required | string Persuit Id of the corresponding RFP |
| proposalId required | string The ID of the proposal |
| questionGroupId required | string or null ID of the question group |
| questionGroupName required | string or null Example: "Group A" Name of the question group |
| questionId required | string ID of the question |
| questionIndex required | number <double> Example: "1" Index of the question This is a 1-based index, so the first question has an index of 1. |
| questionTitle required | string Example: "What is your preferred billing method?" Title of the question |
| questionDescription required | string or null Example: "Please provide details about your billing preferences." Description of the question |
| required required | boolean Example: "true" Denotes (True/False) whether the question is required |
| type required | string (QuestionType) Enum: "CHOICE" "LONG" "MEDIUM" "SHORT" "NUMERIC" "PERCENTAGE" "PRICE" "SINGLE_SELECT" "MULTIPLE_SELECT" "SCALE" |
| options required | string or null Example: "\"Option 1\", \"Option 2\", \"Option 3\", \"Option 4\"" Question options if the type is "SINGLE_SELECT" or "MULTIPLE_SELECT". The value contains all options in a comma-separated, double-quoted format. null if the question type is not "SINGLE_SELECT" or "MULTIPLE_SELECT". |
| firmId required | string ID of the firm |
| firmName required | string Example: "Acme Law Firm" Name of the firm |
| answerId required | string ID of the answer |
| answer required | string or null Example: "Option 1" The answer selected or provided by the firm for this question. If the answer is a "CHOICE" or "SINGLE_SELECT", it will be a string with the selected option. If the answer is a "MULTIPLE_SELECT", all options will be in a comma-separated, double-quoted format. For other types, it will be the provided text or value. |
| comments required | string or null Example: "We prefer fixed pricing." Comments provided by the firm for the question or answer. |
| includedInAnalytics required | boolean Example: "true" Denotes if the corresponding request is included in analytics (e.g. insights). |
[- {
- "persuitId": "string",
- "proposalId": "string",
- "questionGroupId": "string",
- "questionGroupName": "Group A",
- "questionId": "string",
- "questionIndex": "1",
- "questionTitle": "What is your preferred billing method?",
- "questionDescription": "Please provide details about your billing preferences.",
- "required": true,
- "type": "CHOICE",
- "options": "\"Option 1\", \"Option 2\", \"Option 3\", \"Option 4\"",
- "firmId": "string",
- "firmName": "Acme Law Firm",
- "answerId": "string",
- "answer": "Option 1",
- "comments": "We prefer fixed pricing.",
- "includedInAnalytics": true
}
]Supports retrieval and management of PERSUIT users and their assigned roles.
Implements the SCIM v2.0 specification.
Ideal for real-time synchronization with external identity and access management platforms.
Get all active users in PERSUIT for the organisation.
| startIndex | integer <int32> (ScimV2StartIndex) >= 1 Default: 1 Example: startIndex=1 OPTIONAL: return records starting index (1 based). Defaults to 1 |
| count | integer <int32> (ScimV2Count) >= 1 Default: 100 Example: count=100 OPTIONAL: maximum number of results to be returned. Defaults to 100 |
| sortBy | string (ScimV2UserSortBy) Default: "id" Enum: "id" "userName" Example: sortBy=id OPTIONAL: sort by result property. Defaults to 'id' |
| sortOrder | string (ScimV2SortOrder) Default: "ascending" Enum: "ascending" "descending" Example: sortOrder=ascending OPTIONAL: ascending or descending order. Defaults to 'ascending' |
| schemas required | Array of strings Example: ["urn:ietf:params:scim:api:messages:2.0:ListResponse"] SCIM ListResponse Schema. VALUE: ['urn:ietf:params:scim:api:messages:2.0:ListResponse'] |
| totalResults required | integer <int32> Example: "370" Total number of results present for this query. |
| itemsPerPage required | integer <int32> Example: "100" Maximum number of resources requested in this request. |
| startIndex required | integer <int32> Example: "1" Start index of resources retrieved in this request. |
required | Array of objects (ScimV2User) The list of resources requested in this request. |
{- "schemas": [
- "urn:ietf:params:scim:api:messages:2.0:ListResponse"
], - "totalResults": 370,
- "itemsPerPage": 100,
- "startIndex": 1,
- "Resources": [
- {
- "schemas": [
- "urn:ietf:params:scim:schemas:core:2.0:User",
- "urn:ietf:params:scim:schemas:extension:persuit:2.0:User"
], - "id": "65f971ac5db90a679b8cd08c",
- "userName": "john-doe@example.com",
- "displayName": "John Doe",
- "meta": {
- "resourceType": "User",
- "created": "2010-01-01T12:34:56Z",
- "lastModified": "2010-01-01T12:34:56Z",
- "version": "string"
}, - "name": {
- "formatted": "John Doe",
- "familyName": "Doe",
- "givenName": "John",
- "middleName": "string",
- "honorificPrefix": "string",
- "honorificSuffix": "string"
}, - "groups": [
- {
- "value": "15f970ac5d890e677b86608c-group.manager",
- "display": "Legal Group - group.manager",
- "type": "Group"
}
], - "active": true,
- "externalId": "string",
- "nickName": "string",
- "profileUrl": "string",
- "title": "string",
- "userType": "string",
- "preferredLanguage": "string",
- "locale": "string",
- "timezone": "string",
- "password": "string",
- "emails": [
- {
- "value": "john-doe@example.com",
- "display": "john-doe@example.com",
- "type": "string",
- "primary": true
}
], - "addresses": [
- {
- "formatted": "string",
- "type": "string",
- "streetAddress": "string",
- "locality": "string",
- "region": "string",
- "postalCode": "string",
- "country": "string",
- "primary": true
}
], - "phoneNumbers": [
- {
- "value": "string",
- "type": "string"
}
], - "ims": [
- {
- "value": "string",
- "type": "string"
}
], - "photos": [
- {
- "value": "string",
- "type": "string"
}
], - "x509Certificates": [
- {
- "value": "string",
- "display": "string",
- "type": "string",
- "primary": true
}
], - "urn:ietf:params:scim:schemas:extension:persuit:2.0:User": {
- "lastLoginAt": "2010-01-01T12:34:56Z"
}
}
]
}Get an active user with matching ID in PERSUIT for the organisation.
| id required | string Example: 65f971ac5db90a679b8cd08c REQUIRED: the ID of the SCIM User being requested. |
| schemas required | Array of strings Example: ["urn:ietf:params:scim:schemas:core:2.0:User","urn:ietf:params:scim:schemas:extension:persuit:2.0:User"] SCIM user schema. VALUE: ['urn:ietf:params:scim:schemas:core:2.0:User', 'urn:ietf:params:scim:schemas:extension:persuit:2.0:User'] |
| id required | string Example: "65f971ac5db90a679b8cd08c" ID of the user. |
| userName required | string^(.+)@(.+)$ Example: "john-doe@example.com" Primary email address (string) of the user in PERSUIT. |
| displayName | string Example: "John Doe" Fully formatted name of this user. |
required | object (ScimV2Meta_User_) Details of a PERSUIT SCIM resource meta resources. |
object (ScimV2UserName) SCIM user name details. | |
Array of objects (ScimV2UserGroup) SCIM Groups which the user belongs to in PERSUIT. Read Only. | |
| active | boolean Example: "true" Denotes whether the user is active. |
| externalId | string NOT IN USE - External ID of this user. For mapping users between PERSUIT and external systems. |
| nickName | string NOT IN USE |
| profileUrl | string NOT IN USE |
| title | string NOT IN USE |
| userType | string NOT IN USE |
| preferredLanguage | string NOT IN USE |
| locale | string NOT IN USE |
| timezone | string NOT IN USE |
| password | string NOT IN USE |
Array of objects (ScimV2Email) NOT IN USE | |
Array of objects (ScimV2Address) NOT IN USE | |
Array of objects (ScimV2PhoneNumber) NOT IN USE | |
Array of objects (ScimV2Ims) NOT IN USE | |
Array of objects (ScimV2Photo) NOT IN USE | |
Array of objects (ScimV2Certificate) NOT IN USE | |
required | object PERSUIT user custom schema extension. |
{- "schemas": [
- "urn:ietf:params:scim:schemas:core:2.0:User",
- "urn:ietf:params:scim:schemas:extension:persuit:2.0:User"
], - "id": "65f971ac5db90a679b8cd08c",
- "userName": "john-doe@example.com",
- "displayName": "John Doe",
- "meta": {
- "resourceType": "User",
- "created": "2010-01-01T12:34:56Z",
- "lastModified": "2010-01-01T12:34:56Z",
- "version": "string"
}, - "name": {
- "formatted": "John Doe",
- "familyName": "Doe",
- "givenName": "John",
- "middleName": "string",
- "honorificPrefix": "string",
- "honorificSuffix": "string"
}, - "groups": [
- {
- "value": "15f970ac5d890e677b86608c-group.manager",
- "display": "Legal Group - group.manager",
- "type": "Group"
}
], - "active": true,
- "externalId": "string",
- "nickName": "string",
- "profileUrl": "string",
- "title": "string",
- "userType": "string",
- "preferredLanguage": "string",
- "locale": "string",
- "timezone": "string",
- "password": "string",
- "emails": [
- {
- "value": "john-doe@example.com",
- "display": "john-doe@example.com",
- "type": "string",
- "primary": true
}
], - "addresses": [
- {
- "formatted": "string",
- "type": "string",
- "streetAddress": "string",
- "locality": "string",
- "region": "string",
- "postalCode": "string",
- "country": "string",
- "primary": true
}
], - "phoneNumbers": [
- {
- "value": "string",
- "type": "string"
}
], - "ims": [
- {
- "value": "string",
- "type": "string"
}
], - "photos": [
- {
- "value": "string",
- "type": "string"
}
], - "x509Certificates": [
- {
- "value": "string",
- "display": "string",
- "type": "string",
- "primary": true
}
], - "urn:ietf:params:scim:schemas:extension:persuit:2.0:User": {
- "lastLoginAt": "2010-01-01T12:34:56Z"
}
}Delete/Disable a SCIM User with matching ID in PERSUIT for the organisation. This will disable the SCIM User in PERSUIT and they will no longer be available via the SCIM APIs.
| id required | string Example: 65f971ac5db90a679b8cd08c REQUIRED: the ID of the SCIM User being deleted/disabled. |
{- "status": "401",
- "schemas": [
- "urn:ietf:params:scim:api:messages:2.0:Error"
]
}Get all SCIM Groups (roles) in PERSUIT for the organisation.
| startIndex | integer <int32> (ScimV2StartIndex) >= 1 Default: 1 Example: startIndex=1 OPTIONAL: return records starting index (1 based). Defaults to '1' |
| count | integer <int32> (ScimV2Count) >= 1 Default: 100 Example: count=100 OPTIONAL: maximum number of results to be returned. Defaults to '100' |
| sortBy | string (ScimV2GroupSortBy) Default: "id" Enum: "id" "displayName" Example: sortBy=id OPTIONAL: sort by result property. Defaults to 'id' |
| sortOrder | string (ScimV2SortOrder) Default: "ascending" Enum: "ascending" "descending" Example: sortOrder=ascending OPTIONAL: ascending or descending order. Defaults to 'ascending' |
| schemas required | Array of strings Example: ["urn:ietf:params:scim:api:messages:2.0:ListResponse"] SCIM ListResponse Schema. VALUE: ['urn:ietf:params:scim:api:messages:2.0:ListResponse'] |
| totalResults required | integer <int32> Example: "370" Total number of results present for this query. |
| itemsPerPage required | integer <int32> Example: "100" Maximum number of resources requested in this request. |
| startIndex required | integer <int32> Example: "1" Start index of resources retrieved in this request. |
required | Array of objects (ScimV2Group) The list of resources requested in this request. |
{- "schemas": [
- "urn:ietf:params:scim:api:messages:2.0:ListResponse"
], - "totalResults": 370,
- "itemsPerPage": 100,
- "startIndex": 1,
- "Resources": [
- {
- "schemas": [
- "urn:ietf:params:scim:schemas:core:2.0:Group"
], - "id": "15f970ac5d890e677b86608c-group.manager",
- "displayName": "Legal Group - group.manager",
- "meta": {
- "resourceType": "User",
- "created": "2010-01-01T12:34:56Z",
- "lastModified": "2010-01-01T12:34:56Z",
- "version": "string"
}, - "members": [
- {
- "value": "65f971ac5db90a679b8cd08c",
- "type": "User",
- "display": "John Doe"
}
], - "externalId": "string"
}
]
}Get a SCIM Group (role) by ID.
| id required | string Example: 15f970ac5d890e677b86608c-group.manager REQUIRED: the ID of the SCIM Group (role) being requested |
| schemas required | Array of strings Example: ["urn:ietf:params:scim:schemas:core:2.0:Group"] SCIM Group (role) schema. VALUE: ['urn:ietf:params:scim:schemas:core:2.0:Group'] |
| id required | string Example: "15f970ac5d890e677b86608c-group.manager" ID of the SCIM Group (role). |
| displayName required | string Example: "Legal Group - group.manager" Full name of this SCIM Group (role). |
required | object (ScimV2Meta_Group_) Details of a PERSUIT SCIM resource meta resources. |
Array of objects (ScimV2GroupMember) List of all active users with access to this SCIM Group (role). Returned by default. | |
| externalId | string NOT IN USE - External ID of this SCIM Group (role). For mapping SCIM Groups (roles) between PERSUIT and external systems. |
{- "schemas": [
- "urn:ietf:params:scim:schemas:core:2.0:Group"
], - "id": "15f970ac5d890e677b86608c-group.manager",
- "displayName": "Legal Group - group.manager",
- "meta": {
- "resourceType": "User",
- "created": "2010-01-01T12:34:56Z",
- "lastModified": "2010-01-01T12:34:56Z",
- "version": "string"
}, - "members": [
- {
- "value": "65f971ac5db90a679b8cd08c",
- "type": "User",
- "display": "John Doe"
}
], - "externalId": "string"
}Update SCIM Group (role) partially (PATCH) by ID. Supported operations (op):
| id required | string Example: 15f970ac5d890e677b86608c-group.manager REQUIRED: the ID of the SCIM Group (role) being requested. |
| schemas required | Array of strings Example: ["urn:ietf:params:scim:api:messages:2.0:PatchOp"] SCIM resource type schema. VALUE: ['urn:ietf:params:scim:api:messages:2.0:PatchOp'] |
required | Array of objects (ScimV2PatchOperation) SCIM PATCH schema. Details of the PATCH operation. |
| schemas required | Array of strings Example: ["urn:ietf:params:scim:schemas:core:2.0:Group"] SCIM Group (role) schema. VALUE: ['urn:ietf:params:scim:schemas:core:2.0:Group'] |
| id required | string Example: "15f970ac5d890e677b86608c-group.manager" ID of the SCIM Group (role). |
| displayName required | string Example: "Legal Group - group.manager" Full name of this SCIM Group (role). |
required | object (ScimV2Meta_Group_) Details of a PERSUIT SCIM resource meta resources. |
Array of objects (ScimV2GroupMember) List of all active users with access to this SCIM Group (role). Returned by default. | |
| externalId | string NOT IN USE - External ID of this SCIM Group (role). For mapping SCIM Groups (roles) between PERSUIT and external systems. |
{- "schemas": [
- "urn:ietf:params:scim:api:messages:2.0:PatchOp"
], - "Operations": [
- {
- "op": "remove",
- "path": "members[value eq \"65f971ac5db90a679b8cd08c\"]",
- "value": "undefined"
}
]
}{- "schemas": [
- "urn:ietf:params:scim:schemas:core:2.0:Group"
], - "id": "15f970ac5d890e677b86608c-group.manager",
- "displayName": "Legal Group - group.manager",
- "meta": {
- "resourceType": "User",
- "created": "2010-01-01T12:34:56Z",
- "lastModified": "2010-01-01T12:34:56Z",
- "version": "string"
}, - "members": [
- {
- "value": "65f971ac5db90a679b8cd08c",
- "type": "User",
- "display": "John Doe"
}
], - "externalId": "string"
}Get SCIM ServiceProviderConfiguration details.
| schemas required | Array of strings Example: ["urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig"] SCIM service provider schema. VALUE: ['urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig'] |
| documentationUri | string <uri> Example: "https://datatracker.ietf.org/doc/html/rfc7643" SCIM documentation uri. VALUE: 'https://datatracker.ietf.org/doc/html/rfc7643' |
required | object Denotes if SCIM patch operations are supported. |
required | object Denotes if SCIM bulk operations are supported. |
required | object Denotes if SCIM filter operations are supported. |
required | object Denotes if SCIM password change operations are supported. |
required | object Denotes if SCIM sort operations are supported. |
required | object Denotes if SCIM etag configurations are supported. |
required | Array of objects (ScimV2AuthenticationScheme) Specifies the authentication mechanism for the SCIM endpoints. |
required | object (ScimV2Meta_ServiceProviderConfig_) Details of a PERSUIT SCIM resource meta resources. |
{- "schemas": [
- "urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig"
], - "patch": {
- "supported": true
}, - "bulk": {
- "maxPayloadSize": 1,
- "maxOperations": 1,
- "supported": false
}, - "filter": {
- "maxResults": 1,
- "supported": false
}, - "changePassword": {
- "supported": false
}, - "sort": {
- "supported": true
}, - "etag": {
- "supported": false
}, - "authenticationSchemes": [
- {
- "name": "string",
- "description": "string",
- "type": "string",
- "specUri": "string",
- "documentationUri": "string",
- "primary": true
}
], - "meta": {
- "resourceType": "User",
- "created": "2010-01-01T12:34:56Z",
- "lastModified": "2010-01-01T12:34:56Z",
- "version": "string"
}
}Get all SCIM ResourceTypes.
| schemas required | Array of strings Example: ["urn:ietf:params:scim:api:messages:2.0:ListResponse"] SCIM ListResponse Schema. VALUE: ['urn:ietf:params:scim:api:messages:2.0:ListResponse'] |
| totalResults required | integer <int32> Example: "370" Total number of results present for this query. |
| itemsPerPage required | integer <int32> Example: "100" Maximum number of resources requested in this request. |
| startIndex required | integer <int32> Example: "1" Start index of resources retrieved in this request. |
required | Array of objects (ScimV2ResourceType) The list of resources requested in this request. |
{- "schemas": [
- "urn:ietf:params:scim:api:messages:2.0:ListResponse"
], - "totalResults": 370,
- "itemsPerPage": 100,
- "startIndex": 1,
- "Resources": [
- {
- "schemas": [
- "urn:ietf:params:scim:schemas:core:2.0:ResourceType"
], - "id": "User",
- "name": "User",
- "endpoint": "/Users",
- "description": "User Account",
- "schema": "urn:ietf:params:scim:schemas:core:2.0:User",
- "schemaExtensions": [
- {
- "schema": "urn:ietf:params:scim:schemas:core:2.0:User",
- "required": true
}
], - "meta": {
- "resourceType": "User",
- "created": "2010-01-01T12:34:56Z",
- "lastModified": "2010-01-01T12:34:56Z",
- "version": "string"
}
}
]
}Get a SCIM ResourceType by ID.
| id required | string Example: User REQUIRED: the ID of the SCIM ResourceType being requested. |
| schemas required | Array of strings Example: ["urn:ietf:params:scim:schemas:core:2.0:ResourceType"] SCIM resource type schema. VALUE: ['urn:ietf:params:scim:schemas:core:2.0:ResourceType'] |
| id required | string Example: "User" The SCIM resource type's unique id or name. |
| name required | string Example: "User" The SCIM resource type's unique name. |
| endpoint required | string Example: "/Users" The resource type's HTTP-addressable endpoint relative to the Base URL of the service provider. |
| description required | string Example: "User Account" The resource type's description. |
| schema required | string <uri> Example: "urn:ietf:params:scim:schemas:core:2.0:User" The resource type's primary/base schema URI, e.g., "urn:ietf:params:scim:schemas:core:2.0:User". This MUST be equal to the "id" attribute of the associated "Schema" resource. |
required | Array of objects (ScimV2SchemaExtension) A list of URIs of the resource type's schema extensions. |
required | object (ScimV2Meta_ResourceType_) Details of a PERSUIT SCIM resource meta resources. |
{- "schemas": [
- "urn:ietf:params:scim:schemas:core:2.0:ResourceType"
], - "id": "User",
- "name": "User",
- "endpoint": "/Users",
- "description": "User Account",
- "schema": "urn:ietf:params:scim:schemas:core:2.0:User",
- "schemaExtensions": [
- {
- "schema": "urn:ietf:params:scim:schemas:core:2.0:User",
- "required": true
}
], - "meta": {
- "resourceType": "User",
- "created": "2010-01-01T12:34:56Z",
- "lastModified": "2010-01-01T12:34:56Z",
- "version": "string"
}
}Get all SCIM Schemas.
| schemas required | Array of strings Example: ["urn:ietf:params:scim:api:messages:2.0:ListResponse"] SCIM ListResponse Schema. VALUE: ['urn:ietf:params:scim:api:messages:2.0:ListResponse'] |
| totalResults required | integer <int32> Example: "370" Total number of results present for this query. |
| itemsPerPage required | integer <int32> Example: "100" Maximum number of resources requested in this request. |
| startIndex required | integer <int32> Example: "1" Start index of resources retrieved in this request. |
required | Array of objects (ScimV2Schema) The list of resources requested in this request. |
{- "schemas": [
- "urn:ietf:params:scim:api:messages:2.0:ListResponse"
], - "totalResults": 370,
- "itemsPerPage": 100,
- "startIndex": 1,
- "Resources": [
- {
- "id": "urn:ietf:params:scim:schemas:core:2.0:User",
- "name": "User",
- "description": "User Account",
- "meta": {
- "resourceType": "User",
- "created": "2010-01-01T12:34:56Z",
- "lastModified": "2010-01-01T12:34:56Z",
- "version": "string"
}, - "attributes": [
- {
- "name": "string",
- "description": "string",
- "type": "string",
- "subAttributes": [
- { }
], - "multiValued": true,
- "required": true,
- "canonicalValues": [
- "string"
], - "caseExact": true,
- "mutability": "readOnly",
- "returned": "always",
- "uniqueness": "none",
- "referenceTypes": [
- "string"
]
}
]
}
]
}Get a SCIM Schema by ID.
| id required | string Example: urn:ietf:params:scim:schemas:core:2.0:User REQUIRED: the ID of the SCIM Schema being requested. |
| id required | string <uri> Example: "urn:ietf:params:scim:schemas:core:2.0:User" ID (uri) of this schema. |
| name required | string Example: "User" Name of the schema. |
| description required | string Example: "User Account" Description of the schema. |
required | object (ScimV2Meta_Schema_) Details of a PERSUIT SCIM resource meta resources. |
required | Array of objects (ScimV2SchemaAttribute) Attributes of the schema. |
{- "id": "urn:ietf:params:scim:schemas:core:2.0:User",
- "name": "User",
- "description": "User Account",
- "meta": {
- "resourceType": "User",
- "created": "2010-01-01T12:34:56Z",
- "lastModified": "2010-01-01T12:34:56Z",
- "version": "string"
}, - "attributes": [
- {
- "name": "string",
- "description": "string",
- "type": "string",
- "subAttributes": [
- { }
], - "multiValued": true,
- "required": true,
- "canonicalValues": [
- "string"
], - "caseExact": true,
- "mutability": "readOnly",
- "returned": "always",
- "uniqueness": "none",
- "referenceTypes": [
- "string"
]
}
]
}The PERSUIT API uses standard HTTP response codes to indicate the success or failure of API requests. Error responses include detailed information to help you diagnose and resolve issues quickly.
The PERSUIT API returns the following types of status codes:
All error responses (4xx and 5xx status codes) return a JSON object with the following structure:
{
"message": "RFP REQ-67213 does not exist",
"encounteredAt": "2024-01-15T10:30:45.123Z"
}| Status Code | Endpoint Example | Error Message Example | How to Fix |
|---|---|---|---|
| 401 | All endpoints | Authorization header not found in request | Ensure you have a valid authentication token. |
| 403 | /api/v3/rfps/{persuitId} | User [email] is not authorized to access RFP [PERSUIT ID] | Verify your API account has the required scopes. For SCIM endpoints, use an org-level API account. |
| 404 | /api/v3/rfps/{persuitId} | RFP [PERSUIT ID] does not exist | Check if the resource exists and your group/team has access to it. |
| 422 | /api/scim/v2/Groups/{id} | Unsupported SCIM operation.op: [operation]. Currently only remove is supported. | Only use supported SCIM operations. Currently, only 'remove' operations are supported for SCIM PATCH requests. |
| 500 | All endpoints | Internal Server Error encountered. Please contact support@persuit.com with API call and date-time error was encountered. | Retry the request after a brief wait. If the error persists, contact support@persuit.com with the endpoint URL and timestamp. |
The PERSUIT API enforces rate limits to ensure fair usage and maintain service reliability for all consumers. Rate limits are applied per IP address across all API endpoints.
| Scope | Limit | Window |
|---|---|---|
| All endpoints (RFP, Reporting, SCIM) | 100 requests | 5 minutes |
Rate limits apply uniformly across all endpoint and share the same 100-request-per-5-minute allowance per IP address.
Every API response includes the following headers to help you monitor your current rate limit status:
| Header | Description |
|---|---|
X-RateLimit-Limit | The maximum number of requests allowed in the current window (e.g., 100). |
X-RateLimit-Remaining | The number of requests remaining in the current window. |
X-RateLimit-Reset | The time (in seconds) when the current rate limit window resets and the full quota becomes available again. |
When you exceed the rate limit, the API responds with a 429 Too Many Requests status code. The response body will contain a plain text message:
HTTP/1.1 429 Too Many Requests Content-Type: text/plain X-RateLimit-Limit: 100 X-RateLimit-Remaining: 0 X-RateLimit-Reset: 250 Too many requests, please try again later.
If you receive a 429 response, we recommend the following retry strategy:
Retry-After header — This header indicates the number of seconds to wait before making another request.X-RateLimit-Reset header — This header provides the timestamp (in seconds) when your rate limit window resets. Wait until this time before retrying.These safeguards are built in to ensure your integration runs smoothly, recovers automatically from temporary issues, and delivers a reliable and consistent performance.