PERSUIT External API (5.0.0)

License: © PERSUIT

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.

Overview

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.




Table of Contents

SectionDescription
AuthenticationObtain an OAuth 2.0 access token using client credentials to authenticate API requests.
RFPSearch and retrieve requests (RFPs), selected proposals, and associated metadata.
REPORTINGAccess flattened, analytics-ready data across requests, invites, proposals, scorecards, questions, answers, and tracking fields.
SCIM V2 - Users & RolesManage users and roles via the SCIM v2.0 standard for identity provider synchronization.
Handling API ErrorsLearn about standard HTTP response codes, error formats, and how to resolve common issues.
Rate LimitingUnderstand API rate limits, response headers, and recommended retry strategies.

Authentication

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.

Step 1 — Obtain an Access Token

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
}

Step 2 — Call an API Endpoint

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

RFP

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 Request by PERSUIT ID

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.

Authorizations:
oauth2_jwt_token
path Parameters
persuitId
required
string
Example: REQ-123456

REQUIRED: the PERSUIT ID of the RFP being requested.

Responses

Response Schema: application/json
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

Response samples

Content type
application/json
{
  • "access": [
    • {
      }
    ],
  • "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": [
    • {
      }
    ],
  • "pricing": {
    • "items": [
      ],
    • "allowOtherPricingModels": true,
    • "pricingModel": "NO_PREFERENCE",
    • "requestTotalPrice": true,
    • "currency": "string",
    • "description": "string"
    },
  • "matterReference": "string",
  • "reverseAuction": true,
  • "status": "DRAFT",
  • "title": "string",
  • "persuitId": "string",
  • "id": "string"
}

Get Requests

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.

Authorizations:
oauth2_jwt_token
query Parameters
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.

Responses

Response Schema: application/json
Array
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

Response samples

Content type
application/json
[
  • {
    • "access": [
      ],
    • "updatedAt": "2019-08-24T14:15:22Z",
    • "createdAt": "2019-08-24T14:15:22Z",
    • "publishedAt": "2019-08-24T14:15:22Z",
    • "createdBy": {
      },
    • "requestedBy": "string",
    • "invitedFirms": [
      ],
    • "pricing": {
      },
    • "matterReference": "string",
    • "reverseAuction": true,
    • "status": "DRAFT",
    • "title": "string",
    • "persuitId": "string",
    • "id": "string"
    }
]

Get Selected Proposals by PERSUIT ID

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.

Authorizations:
oauth2_jwt_token
path Parameters
persuitId
required
string
Example: REQ-123456

REQUIRED: the PERSUIT ID of the RFP being requested

Responses

Response Schema: application/json
Array
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

Response samples

Content type
application/json
[
  • {
    • "updatedAt": "2019-08-24T14:15:22Z",
    • "createdAt": "2019-08-24T14:15:22Z",
    • "createdBy": {
      },
    • "pricing": {
      },
    • "selectedOn": "2019-08-24T14:15:22Z",
    • "status": "DRAFT",
    • "summary": "string",
    • "subject": "string",
    • "firm": {
      },
    • "rfpId": "string",
    • "id": "string"
    }
]

REPORTING

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 Request Invite Summaries

Get all RFP invite summaries Only invites for non-Rate Review Pro RFPs belonging to your organisation are accessible via this API

Authorizations:
oauth2_jwt_token
query Parameters
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.

Responses

Response Schema: application/json
Array
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

Response samples

Content type
application/json
[
  • {
    • "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 Proposal Scorecard Summaries

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.

Authorizations:
oauth2_jwt_token
query Parameters
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.

Responses

Response Schema: application/json
Array
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

Response samples

Content type
application/json
[
  • {
    • "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 Proposal Summaries

Get all proposal summaries. Only proposals submitted for non-Rate Review Pro RFPs belonging to your organisation are accessible via this API.

Authorizations:
oauth2_jwt_token
query Parameters
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.

Responses

Response Schema: application/json
Array
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

Response samples

Content type
application/json
[
  • {
    • "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 Request Summaries

Get all RFP summaries. Only non-Rate Review Pro RFPs belonging to your organisation are accessible via this API.

Authorizations:
oauth2_jwt_token
query Parameters
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.

Responses

Response Schema: application/json
Array
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

Response samples

Content type
application/json
[
  • {
    • "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 Request Tracking Summaries

Get all RFP tracking summaries Only tracking fields for non-Rate Review Pro RFPs belonging to your organisation are accessible via this API

Authorizations:
oauth2_jwt_token
query Parameters
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.

Responses

Response Schema: application/json
Array
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

Response samples

Content type
application/json
[
  • {
    • "includedInAnalytics": true,
    • "trackingFieldvalue": "string",
    • "trackingFieldType": "PLAIN_TEXT",
    • "trackingFieldName": "string",
    • "trackingFieldId": "string",
    • "persuitId": "string"
    }
]

Get Proposal Answer Summaries

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.

Authorizations:
oauth2_jwt_token
query Parameters
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.

Responses

Response Schema: application/json
Array
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

Response samples

Content type
application/json
[
  • {
    • "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"
    }
]

SCIM V2 - Users & Roles

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 SCIM Users

Get all active users in PERSUIT for the organisation.

Authorizations:
oauth2_jwt_token
query Parameters
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'

Responses

Response Schema:
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']

Response samples

Content type
{
  • "Resources": [
    • {
      }
    ],
  • "startIndex": 1,
  • "itemsPerPage": 100,
  • "totalResults": 370,
  • "schemas": [
    • "urn:ietf:params:scim:api:messages:2.0:ListResponse"
    ]
}

Get a SCIM User by ID

Get an active user with matching ID in PERSUIT for the organisation.

Authorizations:
oauth2_jwt_token
path Parameters
id
required
string
Example: 65f971ac5db90a679b8cd08c

REQUIRED: the ID of the SCIM User being requested.

Responses

Response Schema:
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']

Response samples

Content type
{
  • "urn:ietf:params:scim:schemas:extension:persuit:2.0:User": {
    • "lastLoginAt": "2010-01-01T12:34:56Z"
    },
  • "x509Certificates": [
    • {
      }
    ],
  • "photos": [
    • {
      }
    ],
  • "ims": [
    • {
      }
    ],
  • "phoneNumbers": [
    • {
      }
    ],
  • "addresses": [
    • {
      }
    ],
  • "emails": [
    • {
      }
    ],
  • "password": "string",
  • "timezone": "string",
  • "locale": "string",
  • "preferredLanguage": "string",
  • "userType": "string",
  • "title": "string",
  • "profileUrl": "string",
  • "nickName": "string",
  • "externalId": "string",
  • "active": true,
  • "groups": [],
  • "name": {
    • "honorificSuffix": "string",
    • "honorificPrefix": "string",
    • "middleName": "string",
    • "givenName": "John",
    • "familyName": "Doe",
    • "formatted": "John Doe"
    },
  • "meta": {},
  • "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"
    ]
}

Disable a SCIM User by ID

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.

Authorizations:
oauth2_jwt_token
path Parameters
id
required
string
Example: 65f971ac5db90a679b8cd08c

REQUIRED: the ID of the SCIM User being deleted/disabled.

Responses

Response samples

Content type
{
  • "status": "401",
  • "schemas": [
    • "urn:ietf:params:scim:api:messages:2.0:Error"
    ]
}

Get SCIM Groups

Get all SCIM Groups (roles) in PERSUIT for the organisation.

Authorizations:
oauth2_jwt_token
query Parameters
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'

Responses

Response Schema:
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']

Response samples

Content type
{
  • "Resources": [],
  • "startIndex": 1,
  • "itemsPerPage": 100,
  • "totalResults": 370,
  • "schemas": [
    • "urn:ietf:params:scim:api:messages:2.0:ListResponse"
    ]
}

Get a SCIM Group by ID

Get a SCIM Group (role) by ID.

Authorizations:
oauth2_jwt_token
path Parameters
id
required
string
Example: 15f970ac5d890e677b86608c-group.manager

REQUIRED: the ID of the SCIM Group (role) being requested

Responses

Response Schema:
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']

Response samples

Content type
{}

Update a SCIM Group by ID

Update SCIM Group (role) partially (PATCH) by ID. Supported operations (op):

  1. "remove" - remove a member from the SCIM Group. HTTP PATCH body —> {"schemas":["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations":[{"op":"remove","path":"members[value eq ""]"}]}
Authorizations:
oauth2_jwt_token
path Parameters
id
required
string
Example: 15f970ac5d890e677b86608c-group.manager

REQUIRED: the ID of the SCIM Group (role) being requested.

Request Body schema: application/json
required
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']

Responses

Response Schema:
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']

Request samples

Content type
application/json
{
  • "Operations": [
    • {
      }
    ],
  • "schemas": [
    • "urn:ietf:params:scim:api:messages:2.0:PatchOp"
    ]
}

Response samples

Content type
{}

Get SCIM Service Provider Config

Get SCIM ServiceProviderConfiguration details.

Responses

Response Schema:
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']

Response samples

Content type
{
  • "meta": {},
  • "authenticationSchemes": [
    • {
      }
    ],
  • "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 SCIM Resource Types

Get all SCIM ResourceTypes.

Responses

Response Schema:
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']

Response samples

Content type
{
  • "Resources": [
    • {
      }
    ],
  • "startIndex": 1,
  • "itemsPerPage": 100,
  • "totalResults": 370,
  • "schemas": [
    • "urn:ietf:params:scim:api:messages:2.0:ListResponse"
    ]
}

Get a SCIM Resource Type by ID

Get a SCIM ResourceType by ID.

path Parameters
id
required
string
Example: User

REQUIRED: the ID of the SCIM ResourceType being requested.

Responses

Response Schema:
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']

Response samples

Content type
{
  • "meta": {},
  • "schemaExtensions": [
    • {
      }
    ],
  • "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 SCIM Schemas

Get all SCIM Schemas.

Responses

Response Schema:
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']

Response samples

Content type
{
  • "Resources": [
    • {
      }
    ],
  • "startIndex": 1,
  • "itemsPerPage": 100,
  • "totalResults": 370,
  • "schemas": [
    • "urn:ietf:params:scim:api:messages:2.0:ListResponse"
    ]
}

Get a SCIM Schema by ID

Get a SCIM Schema by ID.

path Parameters
id
required
string
Example: urn:ietf:params:scim:schemas:core:2.0:User

REQUIRED: the ID of the SCIM Schema being requested.

Responses

Response Schema:
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.

Response samples

Content type
{
  • "attributes": [
    • {
      }
    ],
  • "meta": {},
  • "description": "User Account",
  • "name": "User",
  • "id": "urn:ietf:params:scim:schemas:core:2.0:User"
}

Handling API Errors

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.

HTTP Status Code Summary

The PERSUIT API returns the following types of status codes:

  • 2xx (Success): The request was successful. The response body will contain the requested data.
  • 4xx (Client Error): The request contains invalid parameters, is missing required authentication, or the authenticated user lacks necessary permissions. Review the error message and fix the request before retrying.
  • 5xx (Server Error): An unexpected error occurred on the PERSUIT server. These errors are rare and typically temporary. If the issue persists, contact support@persuit.com with the request details and timestamp.

Error Response Format

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"
}

Common Errors and Fixes

Status CodeEndpoint ExampleError Message ExampleHow to Fix
401All endpointsAuthorization header not found in requestEnsure 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 existCheck 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.
500All endpointsInternal 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.

Rate Limiting

Overview

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.

Rate Limit Thresholds

ScopeLimitWindow
All endpoints (RFP, Reporting, SCIM)100 requests5 minutes

Rate limits apply uniformly across all endpoint and share the same 100-request-per-5-minute allowance per IP address.

Rate Limit Response Headers

Every API response includes the following headers to help you monitor your current rate limit status:

HeaderDescription
X-RateLimit-LimitThe maximum number of requests allowed in the current window (e.g., 100).
X-RateLimit-RemainingThe number of requests remaining in the current window.
X-RateLimit-ResetThe time (in seconds) when the current rate limit window resets and the full quota becomes available again.

HTTP 429 — Too Many Requests

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:

Sample Throttled Response

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.

Retry Behavior

If you receive a 429 response, we recommend the following retry strategy:

  1. Check the Retry-After header — This header indicates the number of seconds to wait before making another request.
  2. Check the 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.