Beta
Read the Staged Data
Returns the data this session currently holds, as SAMI terms. It changes nothing: reading never stages, never starts a workflow, and never affects a workflow already running.
The response has the same shape as a Stage Data request body: an object carrying terms and nothing else.
You need an access token (Obtaining An Access Token) and a sessionId from Start a Session. Get the URL to submit against from your Pitchpoint Account Representative.
Use this call to inspect the staged data, not as a copy to send back. A read doesn’t return everything you staged, and it returns some values rounded or respelled. What comes back lists the differences. Posting a response back unchanged would record different data. Keep your own copy of what you sent, and build each new snapshot from that. The API Explorer’s description of this call says a response can be changed and sent back as a request. On the service today it can’t.
Sample
url="https://api.pointservices.com/riskinsight-services-ws/resources/v1/sessions/0000000000013500001/sami"
curl -X GET "${url}" \
-H "Authorization: Bearer your_access_token_here" \
-H "Accept: application/json"
Header Properties
| Property | Value | Required? |
|---|---|---|
| Authorization | Bearer your token | true |
| Content-Type | application/json | false, but recommended |
| Accept | application/json | false |
| X-PPS-UserAlias | your value | false |
| X-PPS-UserAgent | your value | false |
| X-PPS-CorrelationID | your value | false |
This call sends no body, so Content-Type is not required. Sending it anyway costs nothing and is the safer habit: on the POST calls edge protection in deployed environments refuses a request that omits it, with a 403 carrying an HTML body rather than any response documented here.
Accept is not enforced — a request without it is answered normally with JSON — but send it anyway, so that a future change to content negotiation cannot alter what you receive.
X-PPS-CorrelationID is a support-tracing header and is not the same thing as the correlationId field in a request body. Only the body field is recorded against an order and searched by Find Workflows; setting the header globally in your HTTP client does not make your orders findable.
See the Common Headers guide for details on the optional X-PPS-* headers above.
Path Parameters
| Property | Description | Type |
|---|---|---|
| sessionId | (mandatory) The session whose data you want to read. | string |
What comes back
The current snapshot only. Earlier snapshots are kept as history and are never served here, so this always describes the data as it stands now.
Every kind of term you staged comes back. That covers the party terms person, property, participant and company, with employers, residences, bank accounts and the real estate they own (properties) nested inside the person they belong to, and the loan-level terms loanTerms, loanToValue, transactionDetail, loanDetail, refinance, housingExpense and closing.
These differ from what you sent, but match what was recorded, so posting them back changes nothing:
| Difference | Why |
|---|---|
| A term carrying no values at all is not echoed | Only terms with something in them are published. |
housingExpense comes back one term per expense | However you grouped them on the way in, they are recorded and served individually. |
ssn comes back as digits only, so 000-00-0000 reads back as 000000000 | That is how it is recorded. |
Each party term, and each residence, employer and property inside a person, carries a correlationId, even if you didn’t send one | The service generates one when it is first recorded. The loan-level terms carry none. See below. |
An NMLS identifier comes back under the participant’s items, as the key NMLSIdentifier, not under identifiers. | NMLSIdentifier is an accepted items key, so the identifier is kept. |
An amount can come back reformatted: a noteAmount of 425000 reads back as 425000.00 | That is the value that was recorded. |
Every …Percent field comes back rounded to two decimal places, so a noteRatePercent of 6.375 reads back as 6.38 | That is the value that was recorded. |
Each property carries the propertyPurpose it was recorded with: the property term reads back as SubjectProperty whatever you sent, and a person.properties entry with its role in the documented spelling, or with none if it was recorded with none | That is the role that was recorded. See propertyPurpose. |
These lose data. Each one changes what the session holds if you send the response back unchanged:
| Difference | If you post it back |
|---|---|
A participant’s contactPoint phone or fax comes back in the service’s own spellings: type as LANDLINE, MOBILE or FAX, and roleType as HOME, BUSINESS or MOBILE. An email contact point is not echoed. | LANDLINE and MOBILE are not accepted type values, so the phone is discarded. An email contact point, which isn’t echoed, is dropped too. |
A person’s declarations are not echoed. | They are dropped from the staged data. |
A participant’s contactPoint comes back with preferenceIndicator set to false, whatever you sent. | The preference is lost. |
Values you sent may also come back spelled differently, or as Other, because each enum-looking field is recorded against its documented list. See Value Vocabularies.
Each party term carries its own correlationId, inside the term object. It is yours when you supplied one, otherwise a value generated when that party was first recorded. Match an echoed term on it rather than by comparing contents. It identifies that party and nothing else: it is not the session’s correlationId, it is not the one you supply when starting a workflow, and it is not what Find Workflows searches.
Responses
Branch on the Content-Type first, and then on what the body contains. application/json is the terms body described below, with no messages key. application/problem+json is a problem document, with type, title, status, detail and instance: read type, and compare it as the whole URI. Some rejections carry no JSON at all. See Error handling for the whole rule.
200
The data the session holds.
| Property | Description | Type |
|---|---|---|
| terms | (optional) The current snapshot, as an array of terms. Omitted entirely when there is nothing to serve — never sent as an empty array, because Stage Data rejects one. | array |
This response carries no messages array and no session object. It is the staged data and nothing else.
Example, for the data staged by the Stage Data sample. Nothing was sent with a correlationId, so the service generated one for the borrower, the residence and the property:
{
"terms": [
{
"person": {
"correlationId": "00000000000000000001-AAAAAAAAAAA=",
"firstName": "Jane",
"lastName": "Sample",
"ssn": "000000000",
"dob": "01/31/1980",
"homePhone": "5555550100",
"residences": [
{
"correlationId": "00000000000000000002-AAAAAAAAAAA=",
"currentIndicator": true,
"address": {
"addressLine1": "12 Example Avenue",
"addressLine2": "Apt 4B",
"city": "Sampleton",
"state": "NY",
"postalCode": "00000"
}
}
]
}
},
{
"property": {
"correlationId": "00000000000000000003-AAAAAAAAAAA=",
"propertyPurpose": "SubjectProperty",
"propertyUsage": "PrimaryResidence",
"propertyType": "Detached",
"address": {
"addressLine1": "1 Sample Street",
"city": "Sampleton",
"state": "NY",
"postalCode": "00000"
}
}
},
{
"loanTerms": {
"noteAmount": "450000.00",
"noteRatePercent": "6.38",
"loanPurpose": "Purchase",
"mortgageType": "Conventional"
}
}
]
}
The property reads back with its role, SubjectProperty, and the rate reads back rounded to two decimal places, as it was recorded. See What comes back.
A session that has staged nothing answers with an empty object:
{}
{} is not proof that nothing is staged. A snapshot whose terms are all empty also answers {}. The question “is anything staged” is answered by session.dataStaged on Read a Session, not by this body.
401
No credential the platform could accept reached the service.
The body is a JSON problem document, not the messages envelope, and the response carries a WWW-Authenticate: Bearer realm="Helix" challenge. Read the machine-readable part from type; title and detail are human copy and are not contractual.
| Property | Description | Type |
|---|---|---|
| type | (present) An absolute URI identifying the problem. about:blank when no credential was sent at all. | string |
| title | (present) Short human-readable summary. | string |
| status | (present) Repeats the HTTP status code. | number |
| detail | (present) Human-readable explanation. Never machine-parsed. | string |
| instance | (present) An identifier for this one request. Quote it when contacting support. | string |
Examples:
{
"type": "about:blank",
"title": "Unauthorized",
"status": 401,
"detail": "Authentication is required. Present a bearer access token in the Authorization header.",
"instance": "urn:pps:request:0000000000000000000000000000000000000000000000000000"
}
{
"type": "https://pointservices.com/problems/invalid-token",
"title": "The access token was not accepted",
"status": 401,
"detail": "The access token was rejected.",
"instance": "urn:pps:request:0000000000000000000000000000000000000000000000000000"
}
The second form carries WWW-Authenticate: Bearer realm="Helix", error="invalid_token", and is what a token the service will not accept returns.
The invalid-token type deliberately does not say why the token was refused: the platform cannot tell an expired token from a revoked, badly signed or malformed one. Treat every invalid-token the same way.
Refresh your token on a 401, and only on a 401. An expiring token moves a call from 200 to 401, never to 403. Obtain a fresh access token and retry the request once. If it fails again, stop and surface the error rather than looping — repeated attempts with a credential the service has already refused will meet the rate throttle described below.
403
Your credential was understood but you are not permitted to read this session. A session that exists but that you may not read is a 403, not a 404: the session is looked up before your access to it is checked.
A 403 is an authorization decision: your identity was established and the answer is still no. It is never a statement about your token, so refreshing the token will not turn it into a 200. A refused request leaves nothing behind, so there is nothing to clean up.
The body is a problem document (application/problem+json), not the messages envelope, so there is no code to branch on. Its type is one of two values:
type | Meaning |
|---|---|
about:blank | The request was denied before the operation itself ran. |
https://pointservices.com/problems/not-authorized | A policy decision about the specific resource or product you named. |
Example:
{
"type": "https://pointservices.com/problems/not-authorized",
"title": "Not authorized",
"status": 403,
"detail": "The authenticated identity is not permitted to perform this action.",
"instance": "urn:pps:request:0000000000000000000000000000000000000000000000000000"
}
A 403 can also come from the edge, before this service is reached, when a request omits Content-Type or carries a value resembling SQL injection or cross-site scripting. That refusal carries an HTML body, not a problem document, and this service never sees it. Check the Content-Type of the response before you parse it. A value that legitimately contains such text should be encoded — Base64, for instance — rather than sent raw.
404
No session exists with this identifier, or this call is not enabled for your environment. It never means ‘nothing staged yet’ — that is a 200 whose body is {}.
When this API answers, the body is a problem document (application/problem+json) in both cases, and its type tells them apart.
https://pointservices.com/problems/not-found means the identifier you sent did not resolve.
| Property | Description | Type |
|---|---|---|
| type | (present) https://pointservices.com/problems/not-found here. Compare it as the whole URI. | string |
| title | (present) Short human-readable summary. | string |
| status | (present) Repeats the HTTP status code. | number |
| detail | (present) Human-readable explanation naming what was not found. Never machine-parsed. | string |
| instance | (present) An identifier for this one request. Quote it when contacting support. | string |
Example:
{
"type": "https://pointservices.com/problems/not-found",
"title": "No such resource",
"status": 404,
"detail": "Session[0000000000013500001] not found",
"instance": "urn:pps:request:0000000000000000000000000000000000000000000000000000"
}
Treat this as a single outcome: nothing in the body narrows down why the identifier did not resolve. Check the identifier you sent, and the tenancy of the credential you sent it with. An identifier this API has already issued to you is readable the moment you receive it, so a 404 on one is final rather than a race. Retrying will not make it appear.
about:blank means the path itself is not served here, so the request never reached this operation: a wrong host, or an environment where this API is not deployed.
A URL missing the /riskinsight-services-ws/resources/v1 path prefix does not reach this API at all. The 404 then comes from infrastructure in front of it, and carries no body this API defines, so don’t try to parse it. If a 404 has no problem document, check the path prefix before anything else.
429
Refused by a rate throttle at the edge, before this service is reached. The throttle counts requests per source address across every endpoint on both the session and workflow surfaces. Because the edge sends this response before the request reaches the service, it is not described in the OpenAPI specifications or the API Explorer.
The refusal carries no body, no messages array and no Retry-After header, and this service never sees it, so it will not appear in any support trace.
Back off and resume. When following a workflow to completion, an interval that stays clear of the throttle is two seconds for the first two checks, then five, then ten seconds thereafter, with an overall deadline after which you stop and investigate.
500
An unhandled failure inside the service. The body is a problem document (application/problem+json) with type about:blank, not the messages envelope, so branch on the status alone. When you report the error to PPS, quote the document’s instance: it carries the same id as the x-pps-request-id response header, and it is what lets PPS find this exact request.
Retrying this call is safe. This call changes nothing, so it is always safe to read again.