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. |
required | Array of objects (Access) User access details of the RFP |
| updatedAt required | string <date-time> Date-Time when the RFP was last updated 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" |
| publishedAt | string <date-time> Date-Time when the RFP was published. Format: ISO 8601 in UTC. "example": "2010-01-01T12:34:56Z" |
required | object (User) Details of a Persuit User |
| requestedBy required | string Name of the requester of the RFP (free text value provided by the client user) |
required | Array of objects (InvitedFirm) Invited Firms for this RFP |
required | object (Pricing) Pricing details of an RFP |
| matterReference required | string Matter reference of the RFP specified in the tracking section by the client user |
| reverseAuction required | boolean Denotes whether this RFP is using Reverse Auction |
| status required | string (RfpStatusType) Enum: "DRAFT" "OPEN_TO_PROPOSALS" "EVALUATING" "AUCTION_IN_PROGRESS" "COMPLETED" "WITHDRAWN" Status of the RFP |
| title required | string Title of the RFP |
| persuitId required | string PERSUIT ID of the RFP |
| id required | string ID of the RFP |
{- "access": [
- {
- "updatedAt": "2019-08-24T14:15:22Z",
- "createdAt": "2019-08-24T14:15:22Z",
- "user": {
- "disabled": true,
- "email": "string",
- "lastName": "string",
- "firstName": "string",
- "orgId": "string",
- "id": "string"
}, - "accessType": "EDIT"
}
], - "updatedAt": "2019-08-24T14:15:22Z",
- "createdAt": "2019-08-24T14:15:22Z",
- "publishedAt": "2019-08-24T14:15:22Z",
- "createdBy": {
- "disabled": true,
- "email": "string",
- "lastName": "string",
- "firstName": "string",
- "orgId": "string",
- "id": "string"
}, - "requestedBy": "string",
- "invitedFirms": [
- {
- "memberAccess": [
- {
- "updatedAt": "2019-08-24T14:15:22Z",
- "createdAt": "2019-08-24T14:15:22Z",
- "user": {
- "disabled": true,
- "email": "string",
- "lastName": "string",
- "firstName": "string",
- "orgId": "string",
- "id": "string"
}, - "accessType": "EDIT"
}
], - "firm": {
- "name": "string",
- "id": "string"
}, - "statusAt": "2019-08-24T14:15:22Z",
- "status": "INVITED",
- "id": "string"
}
], - "pricing": {
- "items": [
- {
- "rateCard": {
- "allowFirmsToAddEntries": true,
- "rates": [
- {
- "title": "string",
- "id": "string"
}
]
}, - "subItems": [
- {
- "pricingModel": "NO_PREFERENCE",
- "title": "string",
- "id": "string"
}
], - "pricingModel": "NO_PREFERENCE",
- "description": "string",
- "type": "PRICING_ITEM",
- "title": "string",
- "id": "string"
}
], - "allowOtherPricingModels": true,
- "pricingModel": "NO_PREFERENCE",
- "requestTotalPrice": true,
- "currency": "string",
- "description": "string"
}, - "matterReference": "string",
- "reverseAuction": true,
- "status": "DRAFT",
- "title": "string",
- "persuitId": "string",
- "id": "string"
}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. |
required | Array of objects (Access) User access details of the RFP |
| updatedAt required | string <date-time> Date-Time when the RFP was last updated 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" |
| publishedAt | string <date-time> Date-Time when the RFP was published. Format: ISO 8601 in UTC. "example": "2010-01-01T12:34:56Z" |
required | object (User) Details of a Persuit User |
| requestedBy required | string Name of the requester of the RFP (free text value provided by the client user) |
required | Array of objects (InvitedFirm) Invited Firms for this RFP |
required | object (Pricing) Pricing details of an RFP |
| matterReference required | string Matter reference of the RFP specified in the tracking section by the client user |
| reverseAuction required | boolean Denotes whether this RFP is using Reverse Auction |
| status required | string (RfpStatusType) Enum: "DRAFT" "OPEN_TO_PROPOSALS" "EVALUATING" "AUCTION_IN_PROGRESS" "COMPLETED" "WITHDRAWN" Status of the RFP |
| title required | string Title of the RFP |
| persuitId required | string PERSUIT ID of the RFP |
| id required | string ID of the RFP |
[- {
- "access": [
- {
- "updatedAt": "2019-08-24T14:15:22Z",
- "createdAt": "2019-08-24T14:15:22Z",
- "user": {
- "disabled": true,
- "email": "string",
- "lastName": "string",
- "firstName": "string",
- "orgId": "string",
- "id": "string"
}, - "accessType": "EDIT"
}
], - "updatedAt": "2019-08-24T14:15:22Z",
- "createdAt": "2019-08-24T14:15:22Z",
- "publishedAt": "2019-08-24T14:15:22Z",
- "createdBy": {
- "disabled": true,
- "email": "string",
- "lastName": "string",
- "firstName": "string",
- "orgId": "string",
- "id": "string"
}, - "requestedBy": "string",
- "invitedFirms": [
- {
- "memberAccess": [
- {
- "updatedAt": "2019-08-24T14:15:22Z",
- "createdAt": "2019-08-24T14:15:22Z",
- "user": {
- "disabled": true,
- "email": "string",
- "lastName": "string",
- "firstName": "string",
- "orgId": "string",
- "id": "string"
}, - "accessType": "EDIT"
}
], - "firm": {
- "name": "string",
- "id": "string"
}, - "statusAt": "2019-08-24T14:15:22Z",
- "status": "INVITED",
- "id": "string"
}
], - "pricing": {
- "items": [
- {
- "rateCard": {
- "allowFirmsToAddEntries": true,
- "rates": [
- {
- "title": "string",
- "id": "string"
}
]
}, - "subItems": [
- {
- "pricingModel": "NO_PREFERENCE",
- "title": "string",
- "id": "string"
}
], - "pricingModel": "NO_PREFERENCE",
- "description": "string",
- "type": "PRICING_ITEM",
- "title": "string",
- "id": "string"
}
], - "allowOtherPricingModels": true,
- "pricingModel": "NO_PREFERENCE",
- "requestTotalPrice": true,
- "currency": "string",
- "description": "string"
}, - "matterReference": "string",
- "reverseAuction": true,
- "status": "DRAFT",
- "title": "string",
- "persuitId": "string",
- "id": "string"
}
]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 |
| updatedAt required | string <date-time> Date-Time when the proposal was last updated Format: ISO 8601 in UTC. "example": "2010-01-01T12:34:56Z" |
| createdAt required | string <date-time> Date-Time when the proposal was created. Format: ISO 8601 in UTC. "example": "2010-01-01T12:34:56Z" |
required | object (User) Details of a Persuit User |
required | object (ProposalPricing) Pricing details of the Proposal |
| selectedOn | string <date-time> The Date on which the Proposal was first Selected |
| 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 |
| summary required | string The summary of the proposal |
| subject required | string The subject or title of the proposal |
required | object (Org) Organisation details |
| rfpId required | string The ID of the corresponding RFP |
| id required | string The ID of the proposal |
[- {
- "updatedAt": "2019-08-24T14:15:22Z",
- "createdAt": "2019-08-24T14:15:22Z",
- "createdBy": {
- "disabled": true,
- "email": "string",
- "lastName": "string",
- "firstName": "string",
- "orgId": "string",
- "id": "string"
}, - "pricing": {
- "items": [
- {
- "rateCard": [
- {
- "addedByFirm": true,
- "rate": 0.1,
- "name": "string",
- "pricingRateCardItemId": "string",
- "id": "string"
}
], - "hourlyRate": 0.1,
- "proposalPricingSubItems": [
- {
- "hours": 0.1,
- "fee": 0.1,
- "pricingModel": {
- "length": 0.1,
- "property1": "string",
- "property2": "string"
}, - "type": "ProposalPricingFeeSubItem",
- "title": "string"
}
], - "hours": 0.1,
- "percentage": 0.1,
- "fee": 0.1,
- "pricingModel": "NO_PREFERENCE",
- "description": "string",
- "excludedFromScope": true,
- "pricingItemId": "string",
- "id": "string"
}
], - "averageRate": 0.1,
- "comparisonValue": 0.1,
- "totalFee": 0.1,
- "priceType": "TOTAL_PRICE",
- "totalPriceModel": "NO_PREFERENCE"
}, - "selectedOn": "2019-08-24T14:15:22Z",
- "status": "DRAFT",
- "summary": "string",
- "subject": "string",
- "firm": {
- "name": "string",
- "id": "string"
}, - "rfpId": "string",
- "id": "string"
}
]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. |
| includedInAnalytics required | boolean Denotes if the corresponding request is included in analytics (e.g. insights) |
| requestReopenedForFirm required | boolean Denotes (True/False) whether the request was re-opened for the law firm |
| 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) |
| 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) |
| rfpViewed required | boolean Denotes (True/False) whether the law firm has viewed the RFP |
| 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 |
| 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" |
| firmName required | string or null Name of the firm |
| firmId required | string or null ID of the firm |
| persuitId required | string Persuit Id of the corresponding RFP |
| inviteId required | string ID of the invite |
[- {
- "includedInAnalytics": true,
- "requestReopenedForFirm": true,
- "firmAgreedToParticipate": true,
- "conflictCheckCleared": true,
- "rfpViewed": true,
- "inviteStatus": "INVITED",
- "invitedAt": "2019-08-24T14:15:22Z",
- "firmName": "string",
- "firmId": "string",
- "persuitId": "string",
- "inviteId": "string"
}
]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. |
| includedInAnalytics required | boolean Denotes if the corresponding request is included in analytics (e.g. insights) |
| 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) |
| scorecardSubcategoryName required | string or null The name of the scorecard subcategory (null if no scorecard subcategory exists for this scorecard category) |
| scorecardSubcategoryId required | string or null The ID of the scorecard subcategory (null if no scorecard subcategory exists for this scorecard category) |
| numberOfSubcategories required | number <double> The number of scorecard subcategories under this scorecard category |
| 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 |
| 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 |
| scorecardCategoryName required | string The name of the scorecard category |
| scorecardCategoryId required | string The ID of the scorecard category |
| firmName required | string Name of the firm submitting this proposal |
| firmId required | string ID of the firm submitting this proposal |
| proposalId required | string The ID of the proposal |
| persuitId required | string Persuit ID of the corresponding RFP |
[- {
- "includedInAnalytics": true,
- "scorecardSubcategoryScorePercentage": 0.1,
- "scorecardSubcategoryName": "string",
- "scorecardSubcategoryId": "string",
- "numberOfSubcategories": 0.1,
- "scorecardCategoryWeightPercentage": 0.1,
- "scorecardCategoryScorePercentage": 0.1,
- "scorecardCategoryName": "string",
- "scorecardCategoryId": "string",
- "firmName": "string",
- "firmId": "string",
- "proposalId": "string",
- "persuitId": "string"
}
]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. |
| includedInAnalytics required | boolean Denotes if the corresponding request is included in analytics (e.g. insights) |
| 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 |
| firmNAMWOLFMember required | boolean or null Denotes if the firm is a NAMWOLF member |
| firmMWBECertified required | boolean or null Denotes if the firm is MWBE (Minority or Women Owned Business Enterprise) certified |
| firmMANSFIELDRuleCertified required | boolean or null Denotes if the firm is MANSFIELD rule certified |
| percentageOfOriginationCreditToDiverseLawyersLawFirmComment required | string or null Comment provided by law firm for the question percentageOfOriginationCreditToDiverseLawyers null if includeStandardDiversityQuestions is false |
| percentageOfOriginationCreditToDiverseLawyersNotApplicable required | boolean or null Denotes whether the law firm has marked percentageOfOriginationCreditToDiverseLawyers as NOT_APPLICABLE 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 |
| percentageOfWorkCompletedByDiverseLawyersLawFirmComment required | string or null Comment provided by law firm for the question percentageOfWorkCompletedByDiverseLawyers null if includeStandardDiversityQuestions is false |
| percentageOfWorkCompletedByDiverseLawyersNotApplicable required | boolean or null Denotes whether the law firm has marked percentageOfWorkCompletedByDiverseLawyers as NOT_APPLICABLE 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 |
| diverseLeadOrFirstOrSecondChairLawFirmComment required | string or null Comment provided by law firm for the question diverseLeadOrFirstOrSecondChair null if includeStandardDiversityQuestions is false |
| diverseLeadOrFirstOrSecondChairNotApplicable required | boolean or null Denotes whether the law firm has marked diverseLeadOrFirstOrSecondChair as NOT_APPLICABLE null if includeStandardDiversityQuestions is false |
| 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 |
| includeStandardDiversityQuestions required | boolean or null Denotes whether the corresponding RFP requires standard diveristy questions answered |
| priceChangeDuringAuctionPercentage required | number or null <double> Example: "-20.05" Percentage of price change during the auction. |
| priceChangeDuringAuction required | number or null <double> Example: "-2000" Price change during the auction. |
| priceAtAuctionEnd required | number or null <double> Example: "8000" Price at the end of the auction. |
| priceAtAuctionStart required | number or null <double> Example: "10000" Price at the start of the auction. |
| finalTotalPrice required | number or null <double> Final total price of this proposal (null if rfpRequestTotalPrice is/was FALSE when the proposal was created) |
| startingTotalPrice required | number or null <double> Starting total price of this proposal (null if rfpRequestTotalPrice is/was FALSE when the proposal was created) |
| originalCurrency required | string or null The original currency used for the request and proposals in PERSUIT. (3 character ISO currency code) |
| currency required | string or null The currency used for the prices in this API response. (3 character ISO currency code) |
| 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) |
| rfpRequestTotalPrice required | boolean Denotes if the "Request Total Price" checkbox is checked on the RFP |
| 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" |
| selected required | boolean Denotes whether this proposal was selected by the client |
| conflictCheckCleared required | boolean or null Denotes if the law firm has cleared conflict check (null if the corresponding RFP does not require conflict check) |
| conflictCleared | boolean or null Deprecated Denotes if the firm cleared conflict check (null if the corresponding RFP does not require conflict check) |
| 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 |
| 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 |
| 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" |
| firmName required | string or null Name of the firm submitting this proposal |
| firmId required | string or null ID of the firm submitting this proposal |
| 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" |
| rfpRequestedBy required | string or null Name of the requester of the RFP (free text value provided by the client user) |
| rfpTitle required | string or null Title of the RFP |
| inviteId required | string or null The ID of the corresponding invitation to the firm |
| rfpPersuitId | string or null Deprecated Persuit Id of the corresponding RFP |
| persuitId required | string Persuit Id of the corresponding RFP |
| rfpId | string Deprecated The ID of the corresponding RFP |
| proposalId required | string The ID of the proposal |
| id | string Deprecated The ID of the proposal |
[- {
- "includedInAnalytics": true,
- "averageWeightedScore": 0.1,
- "firmNAMWOLFMember": true,
- "firmMWBECertified": true,
- "firmMANSFIELDRuleCertified": true,
- "percentageOfOriginationCreditToDiverseLawyersLawFirmComment": "string",
- "percentageOfOriginationCreditToDiverseLawyersNotApplicable": true,
- "percentageOfOriginationCreditToDiverseLawyers": 0.1,
- "percentageOfWorkCompletedByDiverseLawyersLawFirmComment": "string",
- "percentageOfWorkCompletedByDiverseLawyersNotApplicable": true,
- "percentageOfWorkCompletedByDiverseLawyers": 0.1,
- "diverseLeadOrFirstOrSecondChairLawFirmComment": "string",
- "diverseLeadOrFirstOrSecondChairNotApplicable": true,
- "diverseLeadOrFirstOrSecondChair": true,
- "includeStandardDiversityQuestions": true,
- "priceChangeDuringAuctionPercentage": -20.05,
- "priceChangeDuringAuction": -2000,
- "priceAtAuctionEnd": 8000,
- "priceAtAuctionStart": 10000,
- "finalTotalPrice": 0.1,
- "startingTotalPrice": 0.1,
- "originalCurrency": "string",
- "currency": "string",
- "totalPriceModel": "NO_PREFERENCE",
- "rfpRequestTotalPrice": true,
- "selectedAt": "2019-08-24T14:15:22Z",
- "selected": true,
- "conflictCheckCleared": true,
- "conflictCleared": true,
- "proposalStatus": "DRAFT",
- "status": "DRAFT",
- "submittedAt": "2019-08-24T14:15:22Z",
- "firmName": "string",
- "firmId": "string",
- "rfpSentAt": "2019-08-24T14:15:22Z",
- "rfpRequestedBy": "string",
- "rfpTitle": "string",
- "inviteId": "string",
- "rfpPersuitId": "string",
- "persuitId": "string",
- "rfpId": "string",
- "proposalId": "string",
- "id": "string"
}
]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. |
| groupName required | string Name of the PERSUIT group to which this RFP belongs |
| groupId required | string ID of the PERSUIT group to which this RFP belongs |
| includedInAnalytics required | boolean Denotes if the corresponding request is included in analytics (e.g. insights) |
| 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 |
| 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 |
| adjustedSavingsDescription required | string or null Adjusted savings description provided 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) |
| adjustedBaselineFee required | number or null <double> Adjusted baseline fee 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) |
| adjustedSavings required | number or null <double> Adjusted savings set/overridden by the client (null if savings is not overridden) |
| savingsOverride required | boolean Denotes if savings amount was overridden/adjusted by the client (only managers can override) |
| savingsCalculationMethod required | string (SavingsCalculationMethodType) Enum: "RELATIVE_TO_AVERAGE_STARTING_TOTAL_PRICE" "RELATIVE_TO_HIGHEST_STARTING_TOTAL_PRICE" "WINNER_DELTA" "MEDIAN" Savings Calculation type |
| 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). |
| 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) |
| 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) |
| 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 |
| 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 |
| 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) |
| averageFinalTotalPrice required | number or null <double> Average final 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) |
| averageStartingTotalPrice required | number or null <double> Average starting total price of all 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) |
| lowestFinalTotalPrice required | number or null <double> Lowest final total price among submitted proposals (null if requestTotalPrice is FALSE) |
| selectedProposalId required | string or null ID of the selected proposal (null if zero or multiple proposals have been 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) |
| numberOfSelectedProposals required | number <double> Total number of proposals selected |
| numberOfProposals required | number <double> Total number of proposals submitted (excluding draft proposals) |
| 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" |
| selectedFirmName required | string or null Name of the selected firm (null if zero or multiple firms have been selected) |
| selectedFirmId required | string or null ID of the selected firm (null if zero or multiple firms have been selected) |
| numberOfSelectedFirms required | number <double> Total number of firms selected |
| numberOfFirmsWithProposals required | number <double> Total number of firms which submitted one or more proposals (excluding draft proposals) |
| numberOfParticipatingFirms required | number <double> Total number of firms which agreed to participate |
| numberOfConflictClearedFirms required | number or null <double> Total number of firms which cleared conflict (null if conflict check is not required) |
| numberOfInvitedFirms required | number <double> Total number of invited firms |
| conflictCheckRequired required | boolean Is conflict check / T&Cs / NDA required |
| numberOfRequiredQuestions required | number <double> Total number of Required questions asked by the Client to firms |
| numberOfQuestions required | number <double> Total number of questions asked by the Client to firms |
| 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) |
| isAFA required | boolean Denotes if the request is AFA (Alternative Fee Arrangement). |
| hasPrice required | boolean Denotes if the request or any of the proposals has a non-zero price |
| isTotalComparisonRequest required | boolean Denotes if the request is a total comparison request |
| requestTotalPrice required | boolean Denotes if the "Request Total Price" checkbox is checked or not |
| originalCurrency required | string or null The original currency used for the request and proposals in PERSUIT. (3 character ISO currency code) |
| currency required | string or null The currency used for the prices in this API response. (3 character ISO currency code) |
| 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) |
| 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" |
| 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" |
| reverseAuction required | boolean Denotes whether this RFP is using Reverse Auction |
| 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" |
| 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" |
| 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" |
| 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" |
| 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" |
| createdByUserEmail required | string or null Primary email of the user who created the RFP |
| createdByUserName required | string or null Full name of the user who created the RFP |
| createdByUserId required | string or null ID of the user who created the RFP |
| requestedBy required | string Name of the requester of the RFP (free text value provided by the client user) |
| rfpStatus required | string (RfpStatusType) Enum: "DRAFT" "OPEN_TO_PROPOSALS" "EVALUATING" "AUCTION_IN_PROGRESS" "COMPLETED" "WITHDRAWN" Status of the RFP |
| status | string (RfpStatusType) Enum: "DRAFT" "OPEN_TO_PROPOSALS" "EVALUATING" "AUCTION_IN_PROGRESS" "COMPLETED" "WITHDRAWN" Status of the RFP |
| matterReference required | string Matter reference of the RFP specified in the tracking section by the client user |
| title required | string Title 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 |
| persuitId required | string Persuit Id of the RFP |
| id | string Deprecated ID of the RFP |
[- {
- "groupName": "string",
- "groupId": "string",
- "includedInAnalytics": true,
- "estimatedSavingsPercentage": 0.1,
- "estimatedSavings": 0.1,
- "adjustedSavingsDescription": "string",
- "adjustedSavingsPercentage": 0.1,
- "adjustedBaselineFee": 0.1,
- "adjustedAgreedFee": 0.1,
- "adjustedSavings": 0.1,
- "savingsOverride": true,
- "savingsCalculationMethod": "RELATIVE_TO_AVERAGE_STARTING_TOTAL_PRICE",
- "changeInAverageReverseAuctionTotalPricePercentage": 0.1,
- "averageReverseAuctionStartTotalPriceImpactedByOutlier": true,
- "averageReverseAuctionStartTotalPrice": 0.1,
- "changeInAverageTotalPricePercentage": 0.1,
- "changeInAverageTotalPrice": 0.1,
- "averageFinalTotalPriceImpactedByOutlier": true,
- "averageFinalTotalPrice": 0.1,
- "averageStartingTotalPriceImpactedByOutlier": true,
- "averageStartingTotalPrice": 0.1,
- "highestStartingTotalPrice": 0.1,
- "lowestFinalTotalPrice": 0.1,
- "selectedProposalId": "string",
- "selectedProposalsAverageFinalTotalPrice": 0.1,
- "numberOfSelectedProposals": 0.1,
- "numberOfProposals": 0.1,
- "selectedAt": "2019-08-24T14:15:22Z",
- "selectedFirmName": "string",
- "selectedFirmId": "string",
- "numberOfSelectedFirms": 0.1,
- "numberOfFirmsWithProposals": 0.1,
- "numberOfParticipatingFirms": 0.1,
- "numberOfConflictClearedFirms": 0.1,
- "numberOfInvitedFirms": 0.1,
- "conflictCheckRequired": true,
- "numberOfRequiredQuestions": 0.1,
- "numberOfQuestions": 0.1,
- "pricingModel": "NO_PREFERENCE",
- "isAFA": true,
- "hasPrice": true,
- "isTotalComparisonRequest": true,
- "requestTotalPrice": true,
- "originalCurrency": "string",
- "currency": "string",
- "reverseAuctionVisibilityType": "PRICE_RANKING_ONLY",
- "reverseAuctionEndDate": "2019-08-24T14:15:22Z",
- "reverseAuctionStartDate": "2019-08-24T14:15:22Z",
- "reverseAuction": true,
- "proposalsDueDate": "2019-08-24T14:15:22Z",
- "completedAt": "2019-08-24T14:15:22Z",
- "sentAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "createdAt": "2019-08-24T14:15:22Z",
- "createdByUserEmail": "string",
- "createdByUserName": "string",
- "createdByUserId": "string",
- "requestedBy": "string",
- "rfpStatus": "DRAFT",
- "status": "DRAFT",
- "matterReference": "string",
- "title": "string",
- "requestUseCase": "RATE_REVIEW_PRO",
- "persuitId": "string",
- "id": "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. |
| includedInAnalytics required | boolean Denotes if the corresponding request is included in analytics (e.g. insights) |
| trackingFieldvalue required | string or null Value of the RFP 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 |
| trackingFieldName required | string or null Name of the tracking field |
| trackingFieldId required | string ID of the tracking field |
| persuitId required | string Persuit Id of the corresponding RFP |
[- {
- "includedInAnalytics": true,
- "trackingFieldvalue": "string",
- "trackingFieldType": "PLAIN_TEXT",
- "trackingFieldName": "string",
- "trackingFieldId": "string",
- "persuitId": "string"
}
]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. |
| includedInAnalytics required | boolean Example: "true" Denotes if the corresponding request is included in analytics (e.g. insights). |
| comments required | string or null Example: "We prefer fixed pricing." Comments provided by the firm for the question or 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. |
| answerId required | string ID of the answer |
| firmName required | string Example: "Acme Law Firm" Name of the firm |
| firmId required | string ID of the firm |
| 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". |
| type required | string (QuestionType) Enum: "CHOICE" "LONG" "MEDIUM" "SHORT" "NUMERIC" "PERCENTAGE" "PRICE" "SINGLE_SELECT" "MULTIPLE_SELECT" "SCALE" |
| required required | boolean Example: "true" Denotes (True/False) whether the question is required |
| questionDescription required | string or null Example: "Please provide details about your billing preferences." Description of the question |
| questionTitle required | string Example: "What is your preferred billing method?" Title 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. |
| questionId required | string ID of the question |
| questionGroupName required | string or null Example: "Group A" Name of the question group |
| questionGroupId required | string or null ID of the question group |
| proposalId required | string The ID of the proposal |
| persuitId required | string Persuit Id of the corresponding RFP |
[- {
- "includedInAnalytics": true,
- "comments": "We prefer fixed pricing.",
- "answer": "Option 1",
- "answerId": "string",
- "firmName": "Acme Law Firm",
- "firmId": "string",
- "options": "\"Option 1\", \"Option 2\", \"Option 3\", \"Option 4\"",
- "type": "CHOICE",
- "required": true,
- "questionDescription": "Please provide details about your billing preferences.",
- "questionTitle": "What is your preferred billing method?",
- "questionIndex": "1",
- "questionId": "string",
- "questionGroupName": "Group A",
- "questionGroupId": "string",
- "proposalId": "string",
- "persuitId": "string"
}
]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' |
required | Array of objects (ScimV2User) The list of resources requested in this request. |
| startIndex required | integer <int32> Example: "1" Start index of resources retrieved in this request. |
| itemsPerPage required | integer <int32> Example: "100" Maximum number of resources requested in this request. |
| totalResults required | integer <int32> Example: "370" Total number of results present for this query. |
| 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'] |
{- "Resources": [
- {
- "urn:ietf:params:scim:schemas:extension:persuit:2.0:User": {
- "lastLoginAt": "2010-01-01T12:34:56Z"
}, - "x509Certificates": [
- {
- "primary": true,
- "type": "string",
- "display": "string",
- "value": "string"
}
], - "photos": [
- {
- "type": "string",
- "value": "string"
}
], - "ims": [
- {
- "type": "string",
- "value": "string"
}
], - "phoneNumbers": [
- {
- "type": "string",
- "value": "string"
}
], - "addresses": [
- {
- "primary": true,
- "country": "string",
- "postalCode": "string",
- "region": "string",
- "locality": "string",
- "streetAddress": "string",
- "type": "string",
- "formatted": "string"
}
], - "emails": [
- {
- "primary": true,
- "type": "string",
- "display": "john-doe@example.com",
- "value": "john-doe@example.com"
}
], - "password": "string",
- "timezone": "string",
- "locale": "string",
- "preferredLanguage": "string",
- "userType": "string",
- "title": "string",
- "profileUrl": "string",
- "nickName": "string",
- "externalId": "string",
- "active": true,
- "groups": [
- {
- "type": "Group",
- "display": "Legal Group - group.manager",
- "value": "15f970ac5d890e677b86608c-group.manager"
}
], - "name": {
- "honorificSuffix": "string",
- "honorificPrefix": "string",
- "middleName": "string",
- "givenName": "John",
- "familyName": "Doe",
- "formatted": "John Doe"
}, - "meta": {
- "version": "string",
- "lastModified": "2010-01-01T12:34:56Z",
- "created": "2010-01-01T12:34:56Z",
- "resourceType": "User"
}, - "displayName": "John Doe",
- "userName": "john-doe@example.com",
- "id": "65f971ac5db90a679b8cd08c",
- "schemas": [
- "urn:ietf:params:scim:schemas:core:2.0:User",
- "urn:ietf:params:scim:schemas:extension:persuit:2.0:User"
]
}
], - "startIndex": 1,
- "itemsPerPage": 100,
- "totalResults": 370,
- "schemas": [
- "urn:ietf:params:scim:api:messages:2.0:ListResponse"
]
}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. |
required | object PERSUIT user custom schema extension. |
Array of objects (ScimV2Certificate) NOT IN USE | |
Array of objects (ScimV2Photo) NOT IN USE | |
Array of objects (ScimV2Ims) NOT IN USE | |
Array of objects (ScimV2PhoneNumber) NOT IN USE | |
Array of objects (ScimV2Address) NOT IN USE | |
Array of objects (ScimV2Email) NOT IN USE | |
| password | string NOT IN USE |
| timezone | string NOT IN USE |
| locale | string NOT IN USE |
| preferredLanguage | string NOT IN USE |
| userType | string NOT IN USE |
| title | string NOT IN USE |
| profileUrl | string NOT IN USE |
| nickName | string NOT IN USE |
| externalId | string NOT IN USE - External ID of this user. For mapping users between PERSUIT and external systems. |
| active | boolean Example: "true" Denotes whether the user is active. |
Array of objects (ScimV2UserGroup) SCIM Groups which the user belongs to in PERSUIT. Read Only. | |
object (ScimV2UserName) SCIM user name details. | |
required | object (ScimV2Meta_User_) Details of a PERSUIT SCIM resource meta resources. |
| displayName | string Example: "John Doe" Fully formatted name of this user. |
| userName required | string^(.+)@(.+)$ Example: "john-doe@example.com" Primary email address (string) of the user in PERSUIT. |
| id required | string Example: "65f971ac5db90a679b8cd08c" ID of the user. |
| 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'] |
{- "urn:ietf:params:scim:schemas:extension:persuit:2.0:User": {
- "lastLoginAt": "2010-01-01T12:34:56Z"
}, - "x509Certificates": [
- {
- "primary": true,
- "type": "string",
- "display": "string",
- "value": "string"
}
], - "photos": [
- {
- "type": "string",
- "value": "string"
}
], - "ims": [
- {
- "type": "string",
- "value": "string"
}
], - "phoneNumbers": [
- {
- "type": "string",
- "value": "string"
}
], - "addresses": [
- {
- "primary": true,
- "country": "string",
- "postalCode": "string",
- "region": "string",
- "locality": "string",
- "streetAddress": "string",
- "type": "string",
- "formatted": "string"
}
], - "emails": [
- {
- "primary": true,
- "type": "string",
- "display": "john-doe@example.com",
- "value": "john-doe@example.com"
}
], - "password": "string",
- "timezone": "string",
- "locale": "string",
- "preferredLanguage": "string",
- "userType": "string",
- "title": "string",
- "profileUrl": "string",
- "nickName": "string",
- "externalId": "string",
- "active": true,
- "groups": [
- {
- "type": "Group",
- "display": "Legal Group - group.manager",
- "value": "15f970ac5d890e677b86608c-group.manager"
}
], - "name": {
- "honorificSuffix": "string",
- "honorificPrefix": "string",
- "middleName": "string",
- "givenName": "John",
- "familyName": "Doe",
- "formatted": "John Doe"
}, - "meta": {
- "version": "string",
- "lastModified": "2010-01-01T12:34:56Z",
- "created": "2010-01-01T12:34:56Z",
- "resourceType": "User"
}, - "displayName": "John Doe",
- "userName": "john-doe@example.com",
- "id": "65f971ac5db90a679b8cd08c",
- "schemas": [
- "urn:ietf:params:scim:schemas:core:2.0:User",
- "urn:ietf:params:scim:schemas:extension:persuit:2.0:User"
]
}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' |
required | Array of objects (ScimV2Group) The list of resources requested in this request. |
| startIndex required | integer <int32> Example: "1" Start index of resources retrieved in this request. |
| itemsPerPage required | integer <int32> Example: "100" Maximum number of resources requested in this request. |
| totalResults required | integer <int32> Example: "370" Total number of results present for this query. |
| 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'] |
{- "Resources": [
- {
- "externalId": "string",
- "members": [
- {
- "display": "John Doe",
- "type": "User",
- "value": "65f971ac5db90a679b8cd08c"
}
], - "meta": {
- "version": "string",
- "lastModified": "2010-01-01T12:34:56Z",
- "created": "2010-01-01T12:34:56Z",
- "resourceType": "User"
}, - "displayName": "Legal Group - group.manager",
- "id": "15f970ac5d890e677b86608c-group.manager",
- "schemas": [
- "urn:ietf:params:scim:schemas:core:2.0:Group"
]
}
], - "startIndex": 1,
- "itemsPerPage": 100,
- "totalResults": 370,
- "schemas": [
- "urn:ietf:params:scim:api:messages:2.0:ListResponse"
]
}Get a SCIM Group (role) by ID.
| id required | string Example: 15f970ac5d890e677b86608c-group.manager REQUIRED: the ID of the SCIM Group (role) being requested |
| externalId | string NOT IN USE - External ID of this SCIM Group (role). For mapping SCIM Groups (roles) between PERSUIT and external systems. |
Array of objects (ScimV2GroupMember) List of all active users with access to this SCIM Group (role). Returned by default. | |
required | object (ScimV2Meta_Group_) Details of a PERSUIT SCIM resource meta resources. |
| displayName required | string Example: "Legal Group - group.manager" Full name of this SCIM Group (role). |
| id required | string Example: "15f970ac5d890e677b86608c-group.manager" ID of the SCIM Group (role). |
| 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'] |
{- "externalId": "string",
- "members": [
- {
- "display": "John Doe",
- "type": "User",
- "value": "65f971ac5db90a679b8cd08c"
}
], - "meta": {
- "version": "string",
- "lastModified": "2010-01-01T12:34:56Z",
- "created": "2010-01-01T12:34:56Z",
- "resourceType": "User"
}, - "displayName": "Legal Group - group.manager",
- "id": "15f970ac5d890e677b86608c-group.manager",
- "schemas": [
- "urn:ietf:params:scim:schemas:core:2.0:Group"
]
}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. |
required | Array of objects (ScimV2PatchOperation) SCIM PATCH schema. Details of the PATCH operation. |
| 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'] |
| externalId | string NOT IN USE - External ID of this SCIM Group (role). For mapping SCIM Groups (roles) between PERSUIT and external systems. |
Array of objects (ScimV2GroupMember) List of all active users with access to this SCIM Group (role). Returned by default. | |
required | object (ScimV2Meta_Group_) Details of a PERSUIT SCIM resource meta resources. |
| displayName required | string Example: "Legal Group - group.manager" Full name of this SCIM Group (role). |
| id required | string Example: "15f970ac5d890e677b86608c-group.manager" ID of the SCIM Group (role). |
| 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'] |
{- "Operations": [
- {
- "value": "undefined",
- "path": "members[value eq \"65f971ac5db90a679b8cd08c\"]",
- "op": "remove"
}
], - "schemas": [
- "urn:ietf:params:scim:api:messages:2.0:PatchOp"
]
}{- "externalId": "string",
- "members": [
- {
- "display": "John Doe",
- "type": "User",
- "value": "65f971ac5db90a679b8cd08c"
}
], - "meta": {
- "version": "string",
- "lastModified": "2010-01-01T12:34:56Z",
- "created": "2010-01-01T12:34:56Z",
- "resourceType": "User"
}, - "displayName": "Legal Group - group.manager",
- "id": "15f970ac5d890e677b86608c-group.manager",
- "schemas": [
- "urn:ietf:params:scim:schemas:core:2.0:Group"
]
}Get SCIM ServiceProviderConfiguration details.
required | object (ScimV2Meta_ServiceProviderConfig_) Details of a PERSUIT SCIM resource meta resources. |
required | Array of objects (ScimV2AuthenticationScheme) Specifies the authentication mechanism for the SCIM endpoints. |
required | object Denotes if SCIM etag configurations are supported. |
required | object Denotes if SCIM sort operations are supported. |
required | object Denotes if SCIM password change operations are supported. |
required | object Denotes if SCIM filter operations are supported. |
required | object Denotes if SCIM bulk operations are supported. |
required | object Denotes if SCIM patch operations are supported. |
| documentationUri | string <uri> Example: "https://datatracker.ietf.org/doc/html/rfc7643" SCIM documentation uri. VALUE: 'https://datatracker.ietf.org/doc/html/rfc7643' |
| 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'] |
{- "meta": {
- "version": "string",
- "lastModified": "2010-01-01T12:34:56Z",
- "created": "2010-01-01T12:34:56Z",
- "resourceType": "User"
}, - "authenticationSchemes": [
- {
- "primary": true,
- "documentationUri": "string",
- "specUri": "string",
- "type": "string",
- "description": "string",
- "name": "string"
}
], - "etag": {
- "supported": false
}, - "sort": {
- "supported": true
}, - "changePassword": {
- "supported": false
}, - "filter": {
- "maxResults": 1,
- "supported": false
}, - "bulk": {
- "maxPayloadSize": 1,
- "maxOperations": 1,
- "supported": false
}, - "patch": {
- "supported": true
}, - "schemas": [
- "urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig"
]
}Get all SCIM ResourceTypes.
required | Array of objects (ScimV2ResourceType) The list of resources requested in this request. |
| startIndex required | integer <int32> Example: "1" Start index of resources retrieved in this request. |
| itemsPerPage required | integer <int32> Example: "100" Maximum number of resources requested in this request. |
| totalResults required | integer <int32> Example: "370" Total number of results present for this query. |
| 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'] |
{- "Resources": [
- {
- "meta": {
- "version": "string",
- "lastModified": "2010-01-01T12:34:56Z",
- "created": "2010-01-01T12:34:56Z",
- "resourceType": "User"
}, - "schemaExtensions": [
- {
- "required": true,
- "schema": "urn:ietf:params:scim:schemas:core:2.0:User"
}
], - "schema": "urn:ietf:params:scim:schemas:core:2.0:User",
- "description": "User Account",
- "endpoint": "/Users",
- "name": "User",
- "id": "User",
- "schemas": [
- "urn:ietf:params:scim:schemas:core:2.0:ResourceType"
]
}
], - "startIndex": 1,
- "itemsPerPage": 100,
- "totalResults": 370,
- "schemas": [
- "urn:ietf:params:scim:api:messages:2.0:ListResponse"
]
}Get a SCIM ResourceType by ID.
| id required | string Example: User REQUIRED: the ID of the SCIM ResourceType being requested. |
required | object (ScimV2Meta_ResourceType_) Details of a PERSUIT SCIM resource meta resources. |
required | Array of objects (ScimV2SchemaExtension) A list of URIs of the resource type's schema extensions. |
| 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. |
| description required | string Example: "User Account" The resource type's description. |
| endpoint required | string Example: "/Users" The resource type's HTTP-addressable endpoint relative to the Base URL of the service provider. |
| name required | string Example: "User" The SCIM resource type's unique name. |
| id required | string Example: "User" The SCIM resource type's unique id or name. |
| 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'] |
{- "meta": {
- "version": "string",
- "lastModified": "2010-01-01T12:34:56Z",
- "created": "2010-01-01T12:34:56Z",
- "resourceType": "User"
}, - "schemaExtensions": [
- {
- "required": true,
- "schema": "urn:ietf:params:scim:schemas:core:2.0:User"
}
], - "schema": "urn:ietf:params:scim:schemas:core:2.0:User",
- "description": "User Account",
- "endpoint": "/Users",
- "name": "User",
- "id": "User",
- "schemas": [
- "urn:ietf:params:scim:schemas:core:2.0:ResourceType"
]
}Get all SCIM Schemas.
required | Array of objects (ScimV2Schema) The list of resources requested in this request. |
| startIndex required | integer <int32> Example: "1" Start index of resources retrieved in this request. |
| itemsPerPage required | integer <int32> Example: "100" Maximum number of resources requested in this request. |
| totalResults required | integer <int32> Example: "370" Total number of results present for this query. |
| 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'] |
{- "Resources": [
- {
- "attributes": [
- {
- "referenceTypes": [
- "string"
], - "uniqueness": "none",
- "returned": "always",
- "mutability": "readOnly",
- "caseExact": true,
- "canonicalValues": [
- "string"
], - "required": true,
- "multiValued": true,
- "subAttributes": [
- { }
], - "type": "string",
- "description": "string",
- "name": "string"
}
], - "meta": {
- "version": "string",
- "lastModified": "2010-01-01T12:34:56Z",
- "created": "2010-01-01T12:34:56Z",
- "resourceType": "User"
}, - "description": "User Account",
- "name": "User",
- "id": "urn:ietf:params:scim:schemas:core:2.0:User"
}
], - "startIndex": 1,
- "itemsPerPage": 100,
- "totalResults": 370,
- "schemas": [
- "urn:ietf:params:scim:api:messages:2.0:ListResponse"
]
}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. |
required | Array of objects (ScimV2SchemaAttribute) Attributes of the schema. |
required | object (ScimV2Meta_Schema_) Details of a PERSUIT SCIM resource meta resources. |
| description required | string Example: "User Account" Description of the schema. |
| name required | string Example: "User" Name of the schema. |
| id required | string <uri> Example: "urn:ietf:params:scim:schemas:core:2.0:User" ID (uri) of this schema. |
{- "attributes": [
- {
- "referenceTypes": [
- "string"
], - "uniqueness": "none",
- "returned": "always",
- "mutability": "readOnly",
- "caseExact": true,
- "canonicalValues": [
- "string"
], - "required": true,
- "multiValued": true,
- "subAttributes": [
- { }
], - "type": "string",
- "description": "string",
- "name": "string"
}
], - "meta": {
- "version": "string",
- "lastModified": "2010-01-01T12:34:56Z",
- "created": "2010-01-01T12:34:56Z",
- "resourceType": "User"
}, - "description": "User Account",
- "name": "User",
- "id": "urn:ietf:params:scim:schemas:core:2.0:User"
}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.