Repository: amp-labs/connectors
Pull request #1878 (2025-07-17 21:49:33)

chore: upgrade salesforce to v60.0
## Tests
```
=== RUN   TestBulkDelete
=== PAUSE TestBulkDelete
=== RUN   TestJobInfo
=== PAUSE TestJobInfo
=== RUN   TestGetBulkQueryInfo
=== PAUSE TestGetBulkQueryInfo
=== RUN   TestJobResults
=== PAUSE TestJobResults
=== RUN   TestGetSuccessfulJobResults
=== PAUSE TestGetSuccessfulJobResults
=== RUN   TestGetBulkQueryResults
=== PAUSE TestGetBulkQueryResults
=== RUN   TestBulkQuery
=== PAUSE TestBulkQuery
=== RUN   TestBulkRead
=== PAUSE TestBulkRead
=== RUN   TestBulkWrite
=== PAUSE TestBulkWrite
=== RUN   TestSubscribeConnector
=== PAUSE TestSubscribeConnector
=== RUN   TestCreateMetadata
=== PAUSE TestCreateMetadata
=== RUN   TestListObjectMetadata
=== PAUSE TestListObjectMetadata
=== RUN   TestListObjectMetadataPardot
=== PAUSE TestListObjectMetadataPardot
=== RUN   TestRead
=== PAUSE TestRead
=== RUN   TestSoqlBuilderWithIDs
=== PAUSE TestSoqlBuilderWithIDs
=== RUN   TestSubscriptionEventUpdateUser
=== PAUSE TestSubscriptionEventUpdateUser
=== RUN   TestSubscriptionEventUpdateContact
=== PAUSE TestSubscriptionEventUpdateContact
=== RUN   TestSubscriptionEventProperties
=== PAUSE TestSubscriptionEventProperties
=== RUN   TestWrite
=== PAUSE TestWrite
=== CONT  TestBulkDelete
=== CONT  TestCreateMetadata
=== CONT  TestSubscriptionEventUpdateContact
=== CONT  TestRead
=== CONT  TestListObjectMetadataPardot
=== CONT  TestGetBulkQueryResults
=== CONT  TestGetSuccessfulJobResults
=== CONT  TestSoqlBuilderWithIDs
=== CONT  TestGetBulkQueryInfo
=== CONT  TestSubscriptionEventUpdateUser
--- PASS: TestSubscriptionEventUpdateContact (0.00s)
--- PASS: TestSoqlBuilderWithIDs (0.00s)
=== CONT  TestJobResults
=== CONT  TestJobInfo
=== CONT  TestSubscriptionEventProperties
=== RUN   TestGetBulkQueryInfo/Requesting_BulkQuery_information_invokes_correct_
endpoint
=== PAUSE TestGetBulkQueryInfo/Requesting_BulkQuery_information_invokes_correct_
endpoint
=== CONT  TestListObjectMetadata
=== RUN   TestGetSuccessfulJobResults/GetSuccessfulJobResults_-_endpoint_is_invo
ked
=== CONT  TestWrite
=== RUN   TestListObjectMetadataPardot/At_least_one_object_name_must_be_queried
=== PAUSE TestGetSuccessfulJobResults/GetSuccessfulJobResults_-_endpoint_is_invo
ked
=== RUN   TestJobInfo/Request_fails_due_to_internal_server_error
=== RUN   TestListObjectMetadata/At_least_one_object_name_must_be_queried
--- PASS: TestSubscriptionEventUpdateUser (0.00s)
=== CONT  TestSubscribeConnector
=== CONT  TestBulkWrite
=== RUN   TestRead/Read_object_must_be_included
=== RUN   TestJobResults/Partial_failure_is_parsed
=== RUN   TestCreateMetadata/Server_responded_with_empty_body
=== PAUSE TestCreateMetadata/Server_responded_with_empty_body
=== PAUSE TestRead/Read_object_must_be_included
=== RUN   TestGetBulkQueryResults/GetBulkQueryResults_-_endpoint_is_invoked
=== RUN   TestRead/At_least_one_field_is_requested
=== PAUSE TestRead/At_least_one_field_is_requested
=== PAUSE TestListObjectMetadataPardot/At_least_one_object_name_must_be_queried
=== RUN   TestListObjectMetadataPardot/Successfully_describe_one_object_with_met
adata
=== PAUSE TestJobResults/Partial_failure_is_parsed
=== PAUSE TestJobInfo/Request_fails_due_to_internal_server_error
=== RUN   TestJobResults/Complete_failure_with_descriptive_message
=== RUN   TestBulkDelete/Read_object_must_be_included
=== PAUSE TestJobResults/Complete_failure_with_descriptive_message
=== RUN   TestJobResults/Successful_info_parsed_from_JobCompleted_response
=== PAUSE TestBulkDelete/Read_object_must_be_included
=== PAUSE TestListObjectMetadata/At_least_one_object_name_must_be_queried
=== RUN   TestBulkDelete/CSV_is_required_for_upload
=== RUN   TestRead/Correct_error_message_is_understood_from_JSON_response
=== RUN   TestCreateMetadata/Error_token_expired_is_understood
=== PAUSE TestCreateMetadata/Error_token_expired_is_understood
=== PAUSE TestRead/Correct_error_message_is_understood_from_JSON_response
=== PAUSE TestGetBulkQueryResults/GetBulkQueryResults_-_endpoint_is_invoked
=== PAUSE TestListObjectMetadataPardot/Successfully_describe_one_object_with_met
adata
=== CONT  TestBulkRead
=== CONT  TestBulkQuery
=== RUN   TestCreateMetadata/Successful_response_given_valid_request
=== PAUSE TestCreateMetadata/Successful_response_given_valid_request
=== CONT  TestGetBulkQueryInfo/Requesting_BulkQuery_information_invokes_correct_
endpoint
=== PAUSE TestBulkDelete/CSV_is_required_for_upload
=== RUN   TestBulkDelete/Successful_Job_Create,_CSV_upload,_Job_Update
=== PAUSE TestBulkDelete/Successful_Job_Create,_CSV_upload,_Job_Update
=== RUN   TestListObjectMetadata/Mime_response_header_expected_for_successful_re
sponse
=== RUN   TestRead/Incorrect_key_in_payload
=== PAUSE TestRead/Incorrect_key_in_payload
=== PAUSE TestListObjectMetadata/Mime_response_header_expected_for_successful_re
sponse
=== RUN   TestRead/Incorrect_data_type_in_payload
=== PAUSE TestJobResults/Successful_info_parsed_from_JobCompleted_response
=== RUN   TestJobInfo/Correct_endpoint_is_invoked
=== CONT  TestListObjectMetadataPardot/At_least_one_object_name_must_be_queried
=== RUN   TestBulkWrite/Read_object_must_be_included
=== CONT  TestGetSuccessfulJobResults/GetSuccessfulJobResults_-_endpoint_is_invo
ked
=== PAUSE TestJobInfo/Correct_endpoint_is_invoked
=== CONT  TestListObjectMetadataPardot/Successfully_describe_one_object_with_met
adata
=== PAUSE TestRead/Incorrect_data_type_in_payload
=== RUN   TestListObjectMetadata/Successfully_describe_one_object_with_metadata
=== RUN   TestRead/Next_page_cursor_may_be_missing_in_payload
=== PAUSE TestListObjectMetadata/Successfully_describe_one_object_with_metadata
=== PAUSE TestRead/Next_page_cursor_may_be_missing_in_payload
=== CONT  TestCreateMetadata/Server_responded_with_empty_body
=== RUN   TestRead/Next_page_URL_is_resolved,_when_provided_with_a_string
=== PAUSE TestRead/Next_page_URL_is_resolved,_when_provided_with_a_string
=== RUN   TestRead/Successful_read_with_chosen_fields
=== PAUSE TestRead/Successful_read_with_chosen_fields
=== RUN   TestBulkQuery/Correct_error_message_is_understood_from_JSON_response
=== CONT  TestGetBulkQueryResults/GetBulkQueryResults_-_endpoint_is_invoked
=== RUN   TestBulkRead/Read_object_must_be_included
=== PAUSE TestBulkRead/Read_object_must_be_included
=== RUN   TestBulkRead/At_least_one_field_is_requested
=== PAUSE TestBulkRead/At_least_one_field_is_requested
=== RUN   TestBulkRead/Correct_error_message_is_understood_from_JSON_response
=== PAUSE TestBulkWrite/Read_object_must_be_included
=== RUN   TestBulkWrite/Delete_mode_cannot_be_used_in_BulkWrite
=== PAUSE TestBulkWrite/Delete_mode_cannot_be_used_in_BulkWrite
=== RUN   TestBulkWrite/Upsert_requires_External_ID
=== RUN   TestWrite/Write_object_must_be_included
=== CONT  TestCreateMetadata/Successful_response_given_valid_request
--- PASS: TestSubscriptionEventProperties (0.00s)
--- PASS: TestSubscribeConnector (0.00s)
=== CONT  TestCreateMetadata/Error_token_expired_is_understood
=== PAUSE TestBulkRead/Correct_error_message_is_understood_from_JSON_response
=== PAUSE TestBulkQuery/Correct_error_message_is_understood_from_JSON_response
=== RUN   TestBulkQuery/Launch_bulk_job_with_SOQL_query
=== PAUSE TestBulkQuery/Launch_bulk_job_with_SOQL_query
=== RUN   TestBulkRead/Launch_bulk_job_with_SOQL_query
=== RUN   TestBulkQuery/Include_deleted_items_using_Query_All
=== PAUSE TestBulkRead/Launch_bulk_job_with_SOQL_query
=== PAUSE TestBulkQuery/Include_deleted_items_using_Query_All
=== CONT  TestBulkDelete/Read_object_must_be_included
=== PAUSE TestWrite/Write_object_must_be_included
=== RUN   TestWrite/Write_needs_data_payload
=== PAUSE TestWrite/Write_needs_data_payload
=== RUN   TestWrite/Error_response_understood_for_creating_with_unknown_field
=== PAUSE TestWrite/Error_response_understood_for_creating_with_unknown_field
=== CONT  TestBulkDelete/Successful_Job_Create,_CSV_upload,_Job_Update
=== RUN   TestWrite/Error_response_understood_for_updating_reserved_field
=== PAUSE TestWrite/Error_response_understood_for_updating_reserved_field
=== RUN   TestWrite/Write_must_act_as_an_Update
=== PAUSE TestBulkWrite/Upsert_requires_External_ID
=== PAUSE TestWrite/Write_must_act_as_an_Update
=== RUN   TestWrite/Valid_creation_of_account
=== PAUSE TestWrite/Valid_creation_of_account
=== RUN   TestBulkWrite/CSV_is_required_for_upload
=== PAUSE TestBulkWrite/CSV_is_required_for_upload
=== RUN   TestBulkWrite/Creating_Job_fails_on_bad_response
=== PAUSE TestBulkWrite/Creating_Job_fails_on_bad_response
=== RUN   TestBulkWrite/Create_job_id_must_be_string
=== PAUSE TestBulkWrite/Create_job_id_must_be_string
=== RUN   TestBulkWrite/Created_job_must_have_'Open'_state
=== RUN   TestWrite/OK_Response,_but_with_errors_field
=== PAUSE TestBulkWrite/Created_job_must_have_'Open'_state
=== RUN   TestBulkWrite/Server_rejects_CSV_upload_with_internal_server_error
=== PAUSE TestBulkWrite/Server_rejects_CSV_upload_with_internal_server_error
=== PAUSE TestWrite/OK_Response,_but_with_errors_field
=== RUN   TestBulkWrite/Updating_Job_status_fails
=== CONT  TestBulkDelete/CSV_is_required_for_upload
=== PAUSE TestBulkWrite/Updating_Job_status_fails
=== RUN   TestBulkWrite/Successful_Job_Create,_CSV_upload,_Job_Update
=== PAUSE TestBulkWrite/Successful_Job_Create,_CSV_upload,_Job_Update
=== CONT  TestJobResults/Partial_failure_is_parsed
=== CONT  TestJobResults/Successful_info_parsed_from_JobCompleted_response
--- PASS: TestListObjectMetadataPardot (0.00s)
    --- PASS: TestListObjectMetadataPardot/At_least_one_object_name_must_be_quer
ied (0.00s)
    --- PASS: TestListObjectMetadataPardot/Successfully_describe_one_object_with
_metadata (0.00
s)
               === CONT  TestJobResults/Complete_failure_with_descriptive_messag
e
=== CONT  TestJobInfo/Correct_endpoint_is_invoked
=== CONT  TestJobInfo/Request_fails_due_to_internal_server_error
--- PASS: TestGetBulkQueryResults (0.00s)
    --- PASS: TestGetBulkQueryResults/GetBulkQueryResults_-_endpoint_is_invoked
(0.00s)
--- PASS: TestGetSuccessfulJobResults (0.00s)
    --- PASS: TestGetSuccessfulJobResults/GetSuccessfulJobResults_-_endpoint_is_
invoked (0.00s)
=== CONT  TestListObjectMetadata/At_least_one_object_name_must_be_queried
=== CONT  TestListObjectMetadata/Successfully_describe_one_object_with_metadata
--- PASS: TestGetBulkQueryInfo (0.00s)
    --- PASS: TestGetBulkQueryInfo/Requesting_BulkQuery_information_invokes_corr
ect_endpoint (0
.01s)
               === CONT  TestListObjectMetadata/Mime_response_header_expected_fo
r_successful_response
=== CONT  TestRead/Read_object_must_be_included
=== CONT  TestRead/Successful_read_with_chosen_fields
2025/07/17 14:52:59 ERROR HTTP request failed method=POST url=http://127.0.0.1:5
6498/services/S
oap/m/60.0 correlationId=1e7f9eed-94de-4bcc-8001-205eb8cee526 error="access toke
n invalid: INVALID_SESSION_ID: Invalid Session ID found in SessionHeader: Illega
l Session. Session not\n                found, missing session hash: QV/UUg77RuO
5dh7c3KiUtr6S7iQWwPOd4B/5YwHJ0WE=\n                This error usually occurs aft
er a session expires or a user logs out. Decoder: DataInDbSessionKeyDecoder (HTT
P status 500)"                                                             2025/
07/17 14:52:59 WARN Access token invalid, retrying error="access token invalid:
INVALID_SE
SSION_ID: Invalid Session ID found in SessionHeader: Illegal Session. Session no
t\n                found, missing session hash: QV/UUg77RuO5dh7c3KiUtr6S7iQWwPOd
4B/5YwHJ0WE=\n                This error usually occurs after a session expires
or a user logs out. Decoder: DataInDbSessionKeyDecoder (HTTP status 500)"
                                                            2025/07/17 14:52:59
ERROR HTTP request failed method=GET url=http://127.0.0.1:56484/services/da
ta/v60.0/jobs/ingest correlationId=266eb55a-0ea5-4986-9002-c1e60448a0e6 error="j
son.Unmarshal failed: unexpected end of JSON input"
                              === CONT  TestRead/Next_page_cursor_may_be_missing
_in_payload
=== CONT  TestRead/Next_page_URL_is_resolved,_when_provided_with_a_string
=== CONT  TestRead/Incorrect_data_type_in_payload
=== CONT  TestRead/Incorrect_key_in_payload
--- PASS: TestJobInfo (0.00s)
    --- PASS: TestJobInfo/Request_fails_due_to_internal_server_error (0.00s)
    --- PASS: TestJobInfo/Correct_endpoint_is_invoked (0.00s)
=== CONT  TestRead/At_least_one_field_is_requested
--- PASS: TestBulkDelete (0.00s)
    --- PASS: TestBulkDelete/CSV_is_required_for_upload (0.00s)
    --- PASS: TestBulkDelete/Read_object_must_be_included (0.00s)
    --- PASS: TestBulkDelete/Successful_Job_Create,_CSV_upload,_Job_Update (0.01
s)
=== CONT  TestRead/Correct_error_message_is_understood_from_JSON_response
--- PASS: TestJobResults (0.00s)
    --- PASS: TestJobResults/Successful_info_parsed_from_JobCompleted_response (
0.00s)
    --- PASS: TestJobResults/Partial_failure_is_parsed (0.01s)
    --- PASS: TestJobResults/Complete_failure_with_descriptive_message (0.01s)
=== CONT  TestBulkRead/Correct_error_message_is_understood_from_JSON_response
=== CONT  TestBulkRead/Read_object_must_be_included
=== CONT  TestBulkRead/Launch_bulk_job_with_SOQL_query
=== CONT  TestBulkRead/At_least_one_field_is_requested
=== CONT  TestBulkQuery/Include_deleted_items_using_Query_All
=== CONT  TestBulkQuery/Correct_error_message_is_understood_from_JSON_response
=== CONT  TestBulkQuery/Launch_bulk_job_with_SOQL_query
=== CONT  TestWrite/Write_object_must_be_included
=== CONT  TestWrite/Write_must_act_as_an_Update
--- PASS: TestCreateMetadata (0.00s)
    --- PASS: TestCreateMetadata/Error_token_expired_is_understood (0.01s)
    --- PASS: TestCreateMetadata/Successful_response_given_valid_request (0.01s)
    --- PASS: TestCreateMetadata/Server_responded_with_empty_body (0.01s)
=== CONT  TestWrite/Error_response_understood_for_creating_with_unknown_field
--- PASS: TestListObjectMetadata (0.00s)
    --- PASS: TestListObjectMetadata/At_least_one_object_name_must_be_queried (0
.00s)
    --- PASS: TestListObjectMetadata/Mime_response_header_expected_for_successfu
l_response (0.0
0s)
                   --- PASS: TestListObjectMetadata/Successfully_describe_one_ob
ject_with_metadata (0.01s)
=== CONT  TestWrite/Error_response_understood_for_updating_reserved_field
=== CONT  TestWrite/Write_needs_data_payload
=== CONT  TestWrite/OK_Response,_but_with_errors_field
2025/07/17 14:52:59 ERROR HTTP request failed method=POST url=http://127.0.0.1:5
6513/services/d
ata/v60.0/jobs/query correlationId=19675684-974c-462a-95d6-8853c717b87e error="b
ad request: \nName,BillingCity,IsDeleted FROM Accout\n
      ^\nERROR at Row:1:Column:43\nsObject type 'Accout' is not supported. If yo
u are attempting to use a custom object, be sure to append the '__c' after the e
ntity name. Please reference your WSDL or the describe call for the appropriate
names. (HTTP status 400)"                                                  === C
ONT  TestWrite/Valid_creation_of_account
=== CONT  TestBulkWrite/Read_object_must_be_included
--- PASS: TestBulkRead (0.00s)
    --- PASS: TestBulkRead/Read_object_must_be_included (0.00s)
    --- PASS: TestBulkRead/Launch_bulk_job_with_SOQL_query (0.00s)
    --- PASS: TestBulkRead/Correct_error_message_is_understood_from_JSON_respons
e (0.00s)
    --- PASS: TestBulkRead/At_least_one_field_is_requested (0.00s)
=== CONT  TestBulkWrite/Created_job_must_have_'Open'_state
=== CONT  TestBulkWrite/Create_job_id_must_be_string
2025/07/17 14:52:59 ERROR HTTP request failed method=GET url="http://127.0.0.1:5
6490/services/d
ata/v60.0/query?q=SELECT+Name+FROM+leads" correlationId=1f09ac53-a793-413f-a626-
ba4ecce468d5 error="bad request: \nName,BillingCity,IsDeleted FROM Accout\n
                           ^\nERROR at Row:1:Column:43\nsObject type 'Accout' is
 not supported. If you are attempting to use a custom object, be sure to append
the '__c' after the entity name. Please reference your WSDL or the describe call
 for the appropriate names. (HTTP status 400)"                             --- P
ASS: TestRead (0.00s)
    --- PASS: TestRead/Read_object_must_be_included (0.00s)
    --- PASS: TestRead/Incorrect_key_in_payload (0.00s)
    --- PASS: TestRead/Next_page_cursor_may_be_missing_in_payload (0.00s)
    --- PASS: TestRead/Incorrect_data_type_in_payload (0.00s)
    --- PASS: TestRead/Successful_read_with_chosen_fields (0.00s)
    --- PASS: TestRead/Next_page_URL_is_resolved,_when_provided_with_a_string (0
.00s)
    --- PASS: TestRead/At_least_one_field_is_requested (0.00s)
    --- PASS: TestRead/Correct_error_message_is_understood_from_JSON_response (0
.00s)
=== CONT  TestBulkWrite/Creating_Job_fails_on_bad_response
=== CONT  TestBulkWrite/CSV_is_required_for_upload
2025/07/17 14:52:59 ERROR HTTP request failed method=POST url="http://127.0.0.1:
56524/services/
data/v60.0/sobjects/account/003ak000004dQCUAA2?_HttpMethod=PATCH" correlationId=
40642658-c6d7-4140-b25a-68416ac0725f error="bad request: No such column 'Account
Numer' on sobject of type Account (HTTP status 400)"
                                             === CONT  TestBulkWrite/Upsert_requ
ires_External_ID
=== CONT  TestBulkWrite/Delete_mode_cannot_be_used_in_BulkWrite
2025/07/17 14:52:59 ERROR HTTP request failed method=POST url="http://127.0.0.1:
56525/services/
data/v60.0/sobjects/account/003ak000004dQCUAA2?_HttpMethod=PATCH" correlationId=
90cb7d09-dde0-4d7e-ada7-8b5ceea212fe error="bad request: Unable to create/update
 fields: MasterRecordId. Please check the security settings of this field and ve
rify that it is read/write for your profile or permission set. (HTTP status 400)
"                                                           === CONT  TestBulkWr
ite/Updating_Job_status_fails
=== CONT  TestBulkWrite/Successful_Job_Create,_CSV_upload,_Job_Update
=== CONT  TestBulkWrite/Server_rejects_CSV_upload_with_internal_server_error
2025/07/17 14:52:59 ERROR HTTP request failed method=POST url=http://127.0.0.1:5
6505/services/d
ata/v60.0/jobs/query correlationId=06b25424-f6fe-44db-9bf9-234e365411a5 error="b
ad request: \nName,BillingCity,IsDeleted FROM Accout\n
      ^\nERROR at Row:1:Column:43\nsObject type 'Accout' is not supported. If yo
u are attempting to use a custom object, be sure to append the '__c' after the e
ntity name. Please reference your WSDL or the describe call for the appropriate
names. (HTTP status 400)"                                                  --- P
ASS: TestBulkQuery (0.00s)
    --- PASS: TestBulkQuery/Include_deleted_items_using_Query_All (0.00s)
    --- PASS: TestBulkQuery/Launch_bulk_job_with_SOQL_query (0.00s)
    --- PASS: TestBulkQuery/Correct_error_message_is_understood_from_JSON_respon
se (0.00s)
2025/07/17 14:52:59 ERROR HTTP request failed method=POST url=http://127.0.0.1:5
6515/services/d
ata/v60.0/jobs/ingest correlationId=3d97bb63-8378-480d-84f0-6c74f6577045 error="
json.Unmarshal failed: unexpected end of JSON input"
                              --- PASS: TestWrite (0.00s)
    --- PASS: TestWrite/Write_object_must_be_included (0.00s)
    --- PASS: TestWrite/Write_needs_data_payload (0.00s)
    --- PASS: TestWrite/Error_response_understood_for_creating_with_unknown_fiel
d (0.00s)
    --- PASS: TestWrite/Error_response_understood_for_updating_reserved_field (0
.00s)
    --- PASS: TestWrite/Valid_creation_of_account (0.00s)
    --- PASS: TestWrite/OK_Response,_but_with_errors_field (0.00s)
    --- PASS: TestWrite/Write_must_act_as_an_Update (0.00s)
--- PASS: TestBulkWrite (0.00s)
    --- PASS: TestBulkWrite/CSV_is_required_for_upload (0.00s)
    --- PASS: TestBulkWrite/Read_object_must_be_included (0.00s)
    --- PASS: TestBulkWrite/Upsert_requires_External_ID (0.00s)
    --- PASS: TestBulkWrite/Delete_mode_cannot_be_used_in_BulkWrite (0.00s)
    --- PASS: TestBulkWrite/Create_job_id_must_be_string (0.00s)
    --- PASS: TestBulkWrite/Creating_Job_fails_on_bad_response (0.00s)
    --- PASS: TestBulkWrite/Created_job_must_have_'Open'_state (0.00s)
    --- PASS: TestBulkWrite/Updating_Job_status_fails (0.00s)
    --- PASS: TestBulkWrite/Server_rejects_CSV_upload_with_internal_server_error
 (0.00s)
    --- PASS: TestBulkWrite/Successful_Job_Create,_CSV_upload,_Job_Update (0.00s
)
PASS
ok      github.com/amp-labs/connectors/providers/salesforce     0.413s
?       github.com/amp-labs/connectors/providers/salesforce/internal/pardot
[no test files]
```
<img width="548" height="269" alt="Screenshot 2025-07-17 at 2 54 50 PM" src="https://github.com/user-attachments/assets/a663e726-f902-4179-b67d-70dd784e7337" />

## Salesforce API v60: Change Events and Standard Object CRUD

If you use **change events** and standard object **reads/writes** (CRUD) in Salesforce API, here is what you need to know about upgrading from v59 to v60 (Spring '24):

### 1. Change Events

- **Compatibility:** There are no significant breaking changes in the structure or delivery mechanism of Change Data Capture (CDC) events for standard objects between API v59 and v60.
- **Supported Objects:** All custom objects and a large set of standard objects continue to emit change events in v60, with the naming scheme `<Standard_Object_Name>ChangeEvent` (e.g., `AccountChangeEvent`).
- **Access:** Subscribe to events via `/data/<Standard_Object_Name>ChangeEvent` channels, as before.
- **Payload:** The fields in change event messages map to fields on the source object, delivered with the usual `ChangeEventHeader` and record data[^1].

> There are no documented removals of standard change event support or payload structure that would break code assuming v59 behavior. Ensure you always check for new/undocumented fields and handle unexpected fields gracefully.

### 2. Standard Object Reads and Writes

#### **Reads (GET)**

- Standard object read operations via REST and SOAP APIs remain fully compatible.
- The REST API continues to support queries, SOQL, and direct object GET requests in the same path format, now with `/v60.0/` in the endpoint. Returned fields and data structures are stable for existing objects[^2][^3].
- Always confirm if any new standard fields are present or default behavior changes in field visibility. Cross-reference the [object reference documentation][^4][^5] to spot any new or deprecated fields for your objects.


#### **Writes (POST, PATCH, DELETE)**

- Creating and updating records for standard objects remains unchanged.
- You can continue to use the familiar REST endpoints (e.g., `POST /services/data/v60.0/sobjects/Account`) and update with PATCH, including with sObject collections (bulk updates for up to 200 records per call)[^2][^6].
- Validation rules, triggers, and error messaging remain as before; check for new required fields or validation flows introduced to standard objects, as these are sometimes changed in major releases.


### 3. Notable v60 API Changes Relevant to Your Use Case

**Header Validation**:

- Apex RESTResponse header validation is now stricter: non-HTTP/1.1 compliant headers (e.g., with `/` character) will be rejected. However, this impacts custom integrations and not typical CDC or object CRUD usage unless you set custom headers programmatically.

**Content-Type Default**:

- API calls with missing `Accept` headers default to JSON response. If your reads or writes depended on XML as the implicit default, you must now specify the header explicitly.

**Field and Object Changes**:

- Occasionally, new standard fields or experimental features are added; rarely, fields are deprecated. Always test against your object model and check the current [object reference][^4][^5].


### 4. Recommendation

- Test your CDC listeners and CRUD integrations in a sandbox with v60 endpoints.
- Audit your field usage against the latest object reference to catch any new/deprecated fields.
- Ensure clients and middleware are not relying on missing `Accept` headers for XML defaults.

No widely reported issues exist for CDC or CRUD breaking compatibility moving from v59 to v60, provided you follow these practices[^1][^2][^6][^5].

<div style="text-align: center">⁂</div>

[^1]: https://developer.salesforce.com/docs/atlas.en-us.platform_events.meta/platform_events/platform_events_objects_change_data_capture.htm

[^2]: https://developer.salesforce.com/blogs/2024/04/accessing-object-data-with-salesforce-platform-apis

[^3]: https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_list.htm

[^4]: https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_list.htm

[^5]: https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_asset.htm

[^6]: https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_composite_sobjects_collections_update.htm

[^7]: https://help.salesforce.com/s/articleView?id=release-notes.rn_lwc_versioning.htm\&language=en_US\&release=248\&type=5

[^8]: https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_versions.htm

[^9]: https://resources.docs.salesforce.com/latest/latest/en-us/sfdc/pdf/api_rest.pdf

[^10]: https://salesforce.stackexchange.com/questions/288584/retrieving-a-list-of-change-events

[^11]: https://salesforceshastras.com/all-salesforce-apis-how-when-what-to-use/

[^12]: https://www.youtube.com/watch?v=egVYqciEZyE

[^13]: https://salesforce.stackexchange.com/questions/430181/salesforce-rest-detailed-documentation-regarding-standard-objects-resource

[^14]: https://salesforce.stackexchange.com/questions/362844/how-to-capture-changes-via-api-with-minimal-setup

[^15]: https://salesforce.stackexchange.com/questions/217305/is-the-api-version-available-for-standard-fields-objects-with-which-the-fields-o

[^16]: https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007epea7SAA

[^17]: https://community.make.com/t/salesforce-api-call/32964

[^18]: https://docs.mulesoft.com/release-notes/connector/salesforce-connector-release-notes-mule-4

[^19]: https://salesforce.stackexchange.com/questions/421901/get-a-list-of-things




Patch:
diff --git a/providers/salesforce/connector.go b/providers/salesforce/connector.go
index caea08ff..4500f5e5 100644
--- a/providers/salesforce/connector.go
+++ b/providers/salesforce/connector.go
@@ -10,7 +10,7 @@ import (
 )
 
 const (
-	apiVersion                 = "59.0"
+	apiVersion                 = "60.0"
 	versionPrefix              = "v"
 	version                    = versionPrefix + apiVersion
 	restAPISuffix              = "/services/data/" + version


Test patch:
diff --git a/providers/salesforce/bulk-info_test.go b/providers/salesforce/bulk-info_test.go
index d1c44fa6..9fef4866 100644
--- a/providers/salesforce/bulk-info_test.go
+++ b/providers/salesforce/bulk-info_test.go
@@ -33,7 +33,7 @@ func TestJobInfo(t *testing.T) { //nolint:funlen,gocognit,cyclop,maintidx
 			Input: "750ak000009Bq9OAAS",
 			Server: mockserver.Conditional{
 				Setup: mockserver.ContentJSON(),
-				If:    mockcond.Path("/services/data/v59.0/jobs/ingest/750ak000009Bq9OAAS"),
+				If:    mockcond.Path("/services/data/v60.0/jobs/ingest/750ak000009Bq9OAAS"),
 				Then:  mockserver.Response(http.StatusOK, responseJobInProgress),
 			}.Server(),
 			Comparator: testConciseJobInfoComparator,
@@ -70,7 +70,7 @@ func TestGetBulkQueryInfo(t *testing.T) { // nolint:dupl
 			Input: "750ak000009AVi5AAG",
 			Server: mockserver.Conditional{
 				Setup: mockserver.ContentJSON(),
-				If:    mockcond.Path("/services/data/v59.0/jobs/query/750ak000009AVi5AAG"),
+				If:    mockcond.Path("/services/data/v60.0/jobs/query/750ak000009AVi5AAG"),
 				Then:  mockserver.Response(http.StatusOK, responseAccount),
 			}.Server(),
 			Comparator: testConciseJobInfoComparator,
@@ -111,10 +111,10 @@ func TestJobResults(t *testing.T) { //nolint:funlen,gocognit,cyclop,maintidx
 			Server: mockserver.Switch{
 				Setup: mockserver.ContentJSON(),
 				Cases: []mockserver.Case{{
-					If:   mockcond.Path("/services/data/v59.0/jobs/ingest/750ak000009Dl5bAAC"),
+					If:   mockcond.Path("/services/data/v60.0/jobs/ingest/750ak000009Dl5bAAC"),
 					Then: mockserver.Response(http.StatusOK, responseJobPartialFailure),
 				}, {
-					If:   mockcond.Path("/services/data/v59.0/jobs/ingest/750ak000009Dl5bAAC/failedResults"),
+					If:   mockcond.Path("/services/data/v60.0/jobs/ingest/750ak000009Dl5bAAC/failedResults"),
 					Then: mockserver.Response(http.StatusOK, responseJobPartialFailureDescribed),
 				}},
 			}.Server(),
@@ -197,7 +197,7 @@ func TestGetSuccessfulJobResults(t *testing.T) { // nolint:dupl
 			Input: "750ak000009Dl5bAAC",
 			Server: mockserver.Conditional{
 				Setup: mockserver.ContentJSON(),
-				If:    mockcond.Path("/services/data/v59.0/jobs/ingest/750ak000009Dl5bAAC/successfulResults"),
+				If:    mockcond.Path("/services/data/v60.0/jobs/ingest/750ak000009Dl5bAAC/successfulResults"),
 				Then:  mockserver.Response(http.StatusOK, []byte{}),
 			}.Server(),
 			Comparator:   statusCodeComparator,
@@ -228,7 +228,7 @@ func TestGetBulkQueryResults(t *testing.T) { // nolint:dupl
 			Input: "750ak000009Dl5bAAC",
 			Server: mockserver.Conditional{
 				Setup: mockserver.ContentJSON(),
-				If:    mockcond.Path("/services/data/v59.0/jobs/query/750ak000009Dl5bAAC/results"),
+				If:    mockcond.Path("/services/data/v60.0/jobs/query/750ak000009Dl5bAAC/results"),
 				Then:  mockserver.Response(http.StatusOK, []byte{}),
 			}.Server(),
 			Comparator:   statusCodeComparator,
diff --git a/providers/salesforce/bulk-query_test.go b/providers/salesforce/bulk-query_test.go
index 486d1017..db06b7f8 100644
--- a/providers/salesforce/bulk-query_test.go
+++ b/providers/salesforce/bulk-query_test.go
@@ -29,7 +29,7 @@ func TestBulkQuery(t *testing.T) { //nolint:funlen,gocognit,cyclop,maintidx
 		State:           "UploadComplete",
 		ConcurrencyMode: "Parallel",
 		ContentType:     "CSV",
-		ApiVersion:      59.0,
+		ApiVersion:      60.0,
 		LineEnding:      "LF",
 		ColumnDelimiter: "COMMA",
 	}
@@ -74,7 +74,7 @@ func TestBulkQuery(t *testing.T) { //nolint:funlen,gocognit,cyclop,maintidx
 			Server: mockserver.Conditional{
 				Setup: mockserver.ContentJSON(),
 				If: mockcond.And{
-					mockcond.Path("/services/data/v59.0/jobs/query"),
+					mockcond.Path("/services/data/v60.0/jobs/query"),
 					mockcond.Body(`{
 						"operation":"queryAll",
 						"query":"SELECT Id,Name,BillingCity FROM Account"}`),
diff --git a/providers/salesforce/bulk-read_test.go b/providers/salesforce/bulk-read_test.go
index 6d5a726e..7ba8d5e0 100644
--- a/providers/salesforce/bulk-read_test.go
+++ b/providers/salesforce/bulk-read_test.go
@@ -71,7 +71,7 @@ func TestBulkRead(t *testing.T) { //nolint:funlen,gocognit,cyclop,maintidx
 				State:           "UploadComplete",
 				ConcurrencyMode: "Parallel",
 				ContentType:     "CSV",
-				ApiVersion:      59.0,
+				ApiVersion:      60.0,
 				LineEnding:      "LF",
 				ColumnDelimiter: "COMMA",
 			},
diff --git a/providers/salesforce/bulk-write_test.go b/providers/salesforce/bulk-write_test.go
index fa78bacf..b0ad313b 100644
--- a/providers/salesforce/bulk-write_test.go
+++ b/providers/salesforce/bulk-write_test.go
@@ -123,7 +123,7 @@ func TestBulkWrite(t *testing.T) { //nolint:funlen,gocognit,cyclop,maintidx
 			Server: mockserver.Conditional{
 				Setup: mockserver.ContentJSON(),
 				If: mockcond.And{
-					mockcond.Path("/services/data/v59.0/jobs/ingest"),
+					mockcond.Path("/services/data/v60.0/jobs/ingest"),
 					mockcond.Body(bodyRequest),
 				},
 				Then: mockserver.Response(http.StatusOK, responseCreateJob),
@@ -186,19 +186,19 @@ func createBulkJobServer(
 		Cases: []mockserver.Case{
 			{ // Create job if body matches.
 				If: mockcond.And{
-					mockcond.Path("/services/data/v59.0/jobs/ingest"),
+					mockcond.Path("/services/data/v60.0/jobs/ingest"),
 					mockcond.Body(bodyRequest),
 				},
 				Then: mockserver.Response(http.StatusOK, responseCreateJob),
 			},
 			{ // We expect CSV to be uploaded via this endpoint.
-				If:   mockcond.Path(fmt.Sprintf("/services/data/v59.0/jobs/ingest/%v/batches", jobID)),
+				If:   mockcond.Path(fmt.Sprintf("/services/data/v60.0/jobs/ingest/%v/batches", jobID)),
 				Then: mockserver.Response(http.StatusCreated, []byte{}),
 			},
 			{ // Mark job Completed.
 				If: mockcond.And{
 					mockcond.MethodPATCH(),
-					mockcond.Path(fmt.Sprintf("/services/data/v59.0/jobs/ingest/%v", jobID)),
+					mockcond.Path(fmt.Sprintf("/services/data/v60.0/jobs/ingest/%v", jobID)),
 					mockcond.Body(`{"state":"UploadComplete"}`),
 				},
 				Then: mockserver.Response(http.StatusOK, responseUpdateJob),
diff --git a/providers/salesforce/metadata_test.go b/providers/salesforce/metadata_test.go
index b594670e..15b8d690 100644
--- a/providers/salesforce/metadata_test.go
+++ b/providers/salesforce/metadata_test.go
@@ -40,7 +40,7 @@ func TestListObjectMetadata(t *testing.T) { // nolint:funlen,gocognit,cyclop
 				If: mockcond.Body(`{"allOrNone":false,"compositeRequest":[{
 					"referenceId":"Organization",
 					"method":"GET",
-					"url":"/services/data/v59.0/sobjects/Organization/describe"
+					"url":"/services/data/v60.0/sobjects/Organization/describe"
 				}]}`),
 				Then: mockserver.Response(http.StatusOK, responseOrgMeta),
 			}.Server(),
diff --git a/providers/salesforce/read_test.go b/providers/salesforce/read_test.go
index 4c6523e7..09b0bba9 100644
--- a/providers/salesforce/read_test.go
+++ b/providers/salesforce/read_test.go
@@ -87,7 +87,7 @@ func TestRead(t *testing.T) { //nolint:funlen,gocognit,cyclop,maintidx
 			Server: mockserver.Conditional{
 				Setup: mockserver.ContentJSON(),
 				If: mockcond.And{
-					mockcond.Path("/services/data/v59.0/query"),
+					mockcond.Path("/services/data/v60.0/query"),
 					mockcond.QueryParam("q", "SELECT City FROM leads"),
 				},
 				Then: mockserver.Response(http.StatusOK, responseLeadsFirstPage),
@@ -95,7 +95,7 @@ func TestRead(t *testing.T) { //nolint:funlen,gocognit,cyclop,maintidx
 			Comparator: testroutines.ComparatorPagination,
 			Expected: &common.ReadResult{
 				Rows:     8,
-				NextPage: "/services/data/v59.0/query/01g3A00007lZwLKQA0-2000",
+				NextPage: "/services/data/v60.0/query/01g3A00007lZwLKQA0-2000",
 				Done:     false,
 			},
 			ExpectedErrs: nil,
@@ -109,7 +109,7 @@ func TestRead(t *testing.T) { //nolint:funlen,gocognit,cyclop,maintidx
 			Server: mockserver.Conditional{
 				Setup: mockserver.ContentJSON(),
 				If: mockcond.And{
-					mockcond.Path("/services/data/v59.0/query"),
+					mockcond.Path("/services/data/v60.0/query"),
 					mockcond.Or{
 						mockcond.QueryParam("q", "SELECT AssistantName,Department FROM contacts"),
 						mockcond.QueryParam("q", "SELECT Department,AssistantName FROM contacts"),
diff --git a/providers/salesforce/test/bulk/delete/launch-job-opportunity.json b/providers/salesforce/test/bulk/delete/launch-job-opportunity.json
index 26de8d1d..2e1a8e64 100644
--- a/providers/salesforce/test/bulk/delete/launch-job-opportunity.json
+++ b/providers/salesforce/test/bulk/delete/launch-job-opportunity.json
@@ -8,8 +8,8 @@
   "state": "Open",
   "concurrencyMode": "Parallel",
   "contentType": "CSV",
-  "apiVersion": 59.0,
-  "contentUrl": "services/data/v59.0/jobs/ingest/750ak000009BkrxAAC/batches",
+  "apiVersion": 60.0,
+  "contentUrl": "services/data/v60.0/jobs/ingest/750ak000009BkrxAAC/batches",
   "lineEnding": "LF",
   "columnDelimiter": "COMMA"
 }
diff --git a/providers/salesforce/test/bulk/delete/update-job-opportunity.json b/providers/salesforce/test/bulk/delete/update-job-opportunity.json
index d70d6963..01a49e13 100644
--- a/providers/salesforce/test/bulk/delete/update-job-opportunity.json
+++ b/providers/salesforce/test/bulk/delete/update-job-opportunity.json
@@ -8,5 +8,5 @@
   "state": "UploadComplete",
   "concurrencyMode": "Parallel",
   "contentType": "CSV",
-  "apiVersion": 59.0
+  "apiVersion": 60.0
 }
diff --git a/providers/salesforce/test/bulk/info/complete-failure.json b/providers/salesforce/test/bulk/info/complete-failure.json
index 40892105..f3e5a25d 100644
--- a/providers/salesforce/test/bulk/info/complete-failure.json
+++ b/providers/salesforce/test/bulk/info/complete-failure.json
@@ -9,7 +9,7 @@
   "externalIdFieldName" : "external_id__c",
   "concurrencyMode" : "Parallel",
   "contentType" : "CSV",
-  "apiVersion" : 59.0,
+  "apiVersion" : 60.0,
   "jobType" : "V2Ingest",
   "lineEnding" : "LF",
   "columnDelimiter" : "COMMA",
diff --git a/providers/salesforce/test/bulk/info/in-progress.json b/providers/salesforce/test/bulk/info/in-progress.json
index f93bdfaf..f193194a 100644
--- a/providers/salesforce/test/bulk/info/in-progress.json
+++ b/providers/salesforce/test/bulk/info/in-progress.json
@@ -9,7 +9,7 @@
   "externalIdFieldName" : "external_id__c",
   "concurrencyMode" : "Parallel",
   "contentType" : "CSV",
-  "apiVersion" : 59.0,
+  "apiVersion" : 60.0,
   "jobType" : "V2Ingest",
   "lineEnding" : "LF",
   "columnDelimiter" : "COMMA",
diff --git a/providers/salesforce/test/bulk/info/partial-failure.json b/providers/salesforce/test/bulk/info/partial-failure.json
index 97c96caa..484184d2 100644
--- a/providers/salesforce/test/bulk/info/partial-failure.json
+++ b/providers/salesforce/test/bulk/info/partial-failure.json
@@ -9,7 +9,7 @@
   "externalIdFieldName" : "external_id__c",
   "concurrencyMode" : "Parallel",
   "contentType" : "CSV",
-  "apiVersion" : 59.0,
+  "apiVersion" : 60.0,
   "jobType" : "V2Ingest",
   "lineEnding" : "LF",
   "columnDelimiter" : "COMMA",
diff --git a/providers/salesforce/test/bulk/info/success.json b/providers/salesforce/test/bulk/info/success.json
index 385f67d5..2a92e786 100644
--- a/providers/salesforce/test/bulk/info/success.json
+++ b/providers/salesforce/test/bulk/info/success.json
@@ -9,7 +9,7 @@
   "externalIdFieldName" : "external_id__c",
   "concurrencyMode" : "Parallel",
   "contentType" : "CSV",
-  "apiVersion" : 59.0,
+  "apiVersion" : 60.0,
   "jobType" : "V2Ingest",
   "lineEnding" : "LF",
   "columnDelimiter" : "COMMA",
diff --git a/providers/salesforce/test/bulk/read-launch-job-account.json b/providers/salesforce/test/bulk/read-launch-job-account.json
index c20dd419..7d840643 100644
--- a/providers/salesforce/test/bulk/read-launch-job-account.json
+++ b/providers/salesforce/test/bulk/read-launch-job-account.json
@@ -8,7 +8,7 @@
   "state" : "UploadComplete",
   "concurrencyMode" : "Parallel",
   "contentType" : "CSV",
-  "apiVersion" : 59.0,
+  "apiVersion" : 60.0,
   "lineEnding" : "LF",
   "columnDelimiter" : "COMMA"
 }
diff --git a/providers/salesforce/test/bulk/write/launch-job-opportunity.json b/providers/salesforce/test/bulk/write/launch-job-opportunity.json
index f9f8cb7a..a0fedbaa 100644
--- a/providers/salesforce/test/bulk/write/launch-job-opportunity.json
+++ b/providers/salesforce/test/bulk/write/launch-job-opportunity.json
@@ -9,8 +9,8 @@
   "externalIdFieldName" : "external_id__c",
   "concurrencyMode" : "Parallel",
   "contentType" : "CSV",
-  "apiVersion" : 59.0,
-  "contentUrl" : "services/data/v59.0/jobs/ingest/750ak000009BWKLAA4/batches",
+  "apiVersion" : 60.0,
+  "contentUrl" : "services/data/v60.0/jobs/ingest/750ak000009BWKLAA4/batches",
   "lineEnding" : "LF",
   "columnDelimiter" : "COMMA"
 }
diff --git a/providers/salesforce/test/bulk/write/update-job-opportunity.json b/providers/salesforce/test/bulk/write/update-job-opportunity.json
index 8e27112b..2423d182 100644
--- a/providers/salesforce/test/bulk/write/update-job-opportunity.json
+++ b/providers/salesforce/test/bulk/write/update-job-opportunity.json
@@ -9,5 +9,5 @@
   "externalIdFieldName" : "external_id__c",
   "concurrencyMode" : "Parallel",
   "contentType" : "CSV",
-  "apiVersion" : 59.0
+  "apiVersion" : 60.0
 }
diff --git a/providers/salesforce/test/metadata-organization-sampled.json b/providers/salesforce/test/metadata-organization-sampled.json
index 62e54b99..51de16df 100644
--- a/providers/salesforce/test/metadata-organization-sampled.json
+++ b/providers/salesforce/test/metadata-organization-sampled.json
@@ -653,9 +653,9 @@
         "undeletable": false,
         "updateable": true,
         "urls": {
-          "rowTemplate": "/services/data/v59.0/sobjects/Organization/{ID}",
-          "describe": "/services/data/v59.0/sobjects/Organization/describe",
-          "sobject": "/services/data/v59.0/sobjects/Organization"
+          "rowTemplate": "/services/data/v60.0/sobjects/Organization/{ID}",
+          "describe": "/services/data/v60.0/sobjects/Organization/describe",
+          "sobject": "/services/data/v60.0/sobjects/Organization"
         }
       },
       "httpHeaders": {
diff --git a/providers/salesforce/test/read-list-contacts.json b/providers/salesforce/test/read-list-contacts.json
index 026bfd70..febbf98b 100644
--- a/providers/salesforce/test/read-list-contacts.json
+++ b/providers/salesforce/test/read-list-contacts.json
@@ -5,7 +5,7 @@
     {
       "attributes": {
         "type": "Contact",
-        "url": "/services/data/v59.0/sobjects/Contact/003ak000003dQCGAA2"
+        "url": "/services/data/v60.0/sobjects/Contact/003ak000003dQCGAA2"
       },
       "AccountId": "001ak00000OKNPHAA5",
       "Department": "Finance",
@@ -15,7 +15,7 @@
     {
       "attributes": {
         "type": "Contact",
-        "url": "/services/data/v59.0/sobjects/Contact/003ak000003dQCDAA2"
+        "url": "/services/data/v60.0/sobjects/Contact/003ak000003dQCDAA2"
       },
       "AccountId": "001ak00000OKNPFAA5",
       "Department": "Procurement",
@@ -25,7 +25,7 @@
     {
       "attributes": {
         "type": "Contact",
-        "url": "/services/data/v59.0/sobjects/Contact/003ak000003dQCEAA2"
+        "url": "/services/data/v60.0/sobjects/Contact/003ak000003dQCEAA2"
       },
       "AccountId": "001ak00000OKNPFAA5",
       "Department": "Finance",
@@ -35,7 +35,7 @@
     {
       "attributes": {
         "type": "Contact",
-        "url": "/services/data/v59.0/sobjects/Contact/003ak000003dQCFAA2"
+        "url": "/services/data/v60.0/sobjects/Contact/003ak000003dQCFAA2"
       },
       "AccountId": "001ak00000OKNPGAA5",
       "Department": null,
@@ -45,7 +45,7 @@
     {
       "attributes": {
         "type": "Contact",
-        "url": "/services/data/v59.0/sobjects/Contact/003ak000003dQCHAA2"
+        "url": "/services/data/v60.0/sobjects/Contact/003ak000003dQCHAA2"
       },
       "AccountId": "001ak00000OKNPIAA5",
       "Department": "Internal Operations",
@@ -55,7 +55,7 @@
     {
       "attributes": {
         "type": "Contact",
-        "url": "/services/data/v59.0/sobjects/Contact/003ak000003dQCIAA2"
+        "url": "/services/data/v60.0/sobjects/Contact/003ak000003dQCIAA2"
       },
       "AccountId": "001ak00000OKNPJAA5",
       "Department": "Finance",
@@ -65,7 +65,7 @@
     {
       "attributes": {
         "type": "Contact",
-        "url": "/services/data/v59.0/sobjects/Contact/003ak000003dQCJAA2"
+        "url": "/services/data/v60.0/sobjects/Contact/003ak000003dQCJAA2"
       },
       "AccountId": "001ak00000OKNPJAA5",
       "Department": "Facilities",
@@ -75,7 +75,7 @@
     {
       "attributes": {
         "type": "Contact",
-        "url": "/services/data/v59.0/sobjects/Contact/003ak000003dQCKAA2"
+        "url": "/services/data/v60.0/sobjects/Contact/003ak000003dQCKAA2"
       },
       "AccountId": "001ak00000OKNPKAA5",
       "Department": "Production",
@@ -85,7 +85,7 @@
     {
       "attributes": {
         "type": "Contact",
-        "url": "/services/data/v59.0/sobjects/Contact/003ak000003dQCLAA2"
+        "url": "/services/data/v60.0/sobjects/Contact/003ak000003dQCLAA2"
       },
       "AccountId": "001ak00000OKNPKAA5",
       "Department": "Technology",
@@ -95,7 +95,7 @@
     {
       "attributes": {
         "type": "Contact",
-        "url": "/services/data/v59.0/sobjects/Contact/003ak000003dQCMAA2"
+        "url": "/services/data/v60.0/sobjects/Contact/003ak000003dQCMAA2"
       },
       "AccountId": "001ak00000OKNPLAA5",
       "Department": "Operations",
@@ -105,7 +105,7 @@
     {
       "attributes": {
         "type": "Contact",
-        "url": "/services/data/v59.0/sobjects/Contact/003ak000003dQCNAA2"
+        "url": "/services/data/v60.0/sobjects/Contact/003ak000003dQCNAA2"
       },
       "AccountId": "001ak00000OKNPLAA5",
       "Department": "Warehouse Mgmt",
@@ -115,7 +115,7 @@
     {
       "attributes": {
         "type": "Contact",
-        "url": "/services/data/v59.0/sobjects/Contact/003ak000003dQCOAA2"
+        "url": "/services/data/v60.0/sobjects/Contact/003ak000003dQCOAA2"
       },
       "AccountId": "001ak00000OKNPMAA5",
       "Department": "Administration",
@@ -125,7 +125,7 @@
     {
       "attributes": {
         "type": "Contact",
-        "url": "/services/data/v59.0/sobjects/Contact/003ak000003dQCPAA2"
+        "url": "/services/data/v60.0/sobjects/Contact/003ak000003dQCPAA2"
       },
       "AccountId": "001ak00000OKNPKAA5",
       "Department": "Executive Team",
@@ -135,7 +135,7 @@
     {
       "attributes": {
         "type": "Contact",
-        "url": "/services/data/v59.0/sobjects/Contact/003ak000003dQCQAA2"
+        "url": "/services/data/v60.0/sobjects/Contact/003ak000003dQCQAA2"
       },
       "AccountId": "001ak00000OKNPNAA5",
       "Department": "Finance",
@@ -145,7 +145,7 @@
     {
       "attributes": {
         "type": "Contact",
-        "url": "/services/data/v59.0/sobjects/Contact/003ak000003dQCRAA2"
+        "url": "/services/data/v60.0/sobjects/Contact/003ak000003dQCRAA2"
       },
       "AccountId": "001ak00000OKNPOAA5",
       "Department": "Executive Team",
@@ -155,7 +155,7 @@
     {
       "attributes": {
         "type": "Contact",
-        "url": "/services/data/v59.0/sobjects/Contact/003ak000003dQCSAA2"
+        "url": "/services/data/v60.0/sobjects/Contact/003ak000003dQCSAA2"
       },
       "AccountId": "001ak00000OKNPOAA5",
       "Department": "Production",
@@ -165,7 +165,7 @@
     {
       "attributes": {
         "type": "Contact",
-        "url": "/services/data/v59.0/sobjects/Contact/003ak000003dQCTAA2"
+        "url": "/services/data/v60.0/sobjects/Contact/003ak000003dQCTAA2"
       },
       "AccountId": "001ak00000OKNPPAA5",
       "Department": "Technology",
@@ -175,7 +175,7 @@
     {
       "attributes": {
         "type": "Contact",
-        "url": "/services/data/v59.0/sobjects/Contact/003ak000003dQCUAA2"
+        "url": "/services/data/v60.0/sobjects/Contact/003ak000003dQCUAA2"
       },
       "AccountId": "001ak00000OKNPKAA5",
       "Department": "Finance",
@@ -185,7 +185,7 @@
     {
       "attributes": {
         "type": "Contact",
-        "url": "/services/data/v59.0/sobjects/Contact/003ak000003dQCVAA2"
+        "url": "/services/data/v60.0/sobjects/Contact/003ak000003dQCVAA2"
       },
       "AccountId": "001ak00000OKNPQAA5",
       "Department": null,
@@ -195,7 +195,7 @@
     {
       "attributes": {
         "type": "Contact",
-        "url": "/services/data/v59.0/sobjects/Contact/003ak000003dQCWAA2"
+        "url": "/services/data/v60.0/sobjects/Contact/003ak000003dQCWAA2"
       },
       "AccountId": "001ak00000OKNPQAA5",
       "Department": null,
diff --git a/providers/salesforce/test/read-list-leads.json b/providers/salesforce/test/read-list-leads.json
index 903d0e25..0923ac82 100644
--- a/providers/salesforce/test/read-list-leads.json
+++ b/providers/salesforce/test/read-list-leads.json
@@ -1,12 +1,12 @@
 {
   "totalSize": 8,
   "done": true,
-  "nextRecordsUrl": "/services/data/v59.0/query/01g3A00007lZwLKQA0-2000",
+  "nextRecordsUrl": "/services/data/v60.0/query/01g3A00007lZwLKQA0-2000",
   "records": [
     {
       "attributes": {
         "type": "Lead",
-        "url": "/services/data/v59.0/sobjects/Lead/00Qak00000696HFEAY"
+        "url": "/services/data/v60.0/sobjects/Lead/00Qak00000696HFEAY"
       },
       "Address": {
         "city": "Tallahassee",
@@ -25,7 +25,7 @@
     {
       "attributes": {
         "type": "Lead",
-        "url": "/services/data/v59.0/sobjects/Lead/00Qak00000696HGEAY"
+        "url": "/services/data/v60.0/sobjects/Lead/00Qak00000696HGEAY"
       },
       "Address": {
         "city": null,
@@ -44,7 +44,7 @@
     {
       "attributes": {
         "type": "Lead",
-        "url": "/services/data/v59.0/sobjects/Lead/00Qak00000696HHEAY"
+        "url": "/services/data/v60.0/sobjects/Lead/00Qak00000696HHEAY"
       },
       "Address": {
         "city": null,
@@ -63,7 +63,7 @@
     {
       "attributes": {
         "type": "Lead",
-        "url": "/services/data/v59.0/sobjects/Lead/00Qak00000696HIEAY"
+        "url": "/services/data/v60.0/sobjects/Lead/00Qak00000696HIEAY"
       },
       "Address": {
         "city": null,
@@ -82,7 +82,7 @@
     {
       "attributes": {
         "type": "Lead",
-        "url": "/services/data/v59.0/sobjects/Lead/00Qak00000696HJEAY"
+        "url": "/services/data/v60.0/sobjects/Lead/00Qak00000696HJEAY"
       },
       "Address": {
         "city": null,
@@ -101,7 +101,7 @@
     {
       "attributes": {
         "type": "Lead",
-        "url": "/services/data/v59.0/sobjects/Lead/00Qak00000696HKEAY"
+        "url": "/services/data/v60.0/sobjects/Lead/00Qak00000696HKEAY"
       },
       "Address": {
         "city": null,
@@ -120,7 +120,7 @@
     {
       "attributes": {
         "type": "Lead",
-        "url": "/services/data/v59.0/sobjects/Lead/00Qak00000696HLEAY"
+        "url": "/services/data/v60.0/sobjects/Lead/00Qak00000696HLEAY"
       },
       "Address": {
         "city": null,
@@ -139,7 +139,7 @@
     {
       "attributes": {
         "type": "Lead",
-        "url": "/services/data/v59.0/sobjects/Lead/00Qak00000696HMEAY"
+        "url": "/services/data/v60.0/sobjects/Lead/00Qak00000696HMEAY"
       },
       "Address": {
         "city": null,
diff --git a/test/utils/mockutils/mockserver/README.md b/test/utils/mockutils/mockserver/README.md
index bd441070..ce164a1a 100644
--- a/test/utils/mockutils/mockserver/README.md
+++ b/test/utils/mockutils/mockserver/README.md
@@ -1,7 +1,7 @@
 # Description
 
-This folder contains utility methods to mock API calls made by connectors to provider APIs. 
-It offers several types of mock servers to simulate different scenarios by evaluating incoming 
+This folder contains utility methods to mock API calls made by connectors to provider APIs.
+It offers several types of mock servers to simulate different scenarios by evaluating incoming
 requests and returning appropriate responses.
 
 ## Mock Servers
@@ -21,7 +21,7 @@ Server: httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.
 	_, _ = w.Write(data)
 })),
 ```
-For more complex connectors, this approach becomes unwieldy. 
+For more complex connectors, this approach becomes unwieldy.
 A connector may make multiple API calls, each requiring specific request conditions to be met.
 This package simplifies such scenarios.
 
@@ -47,16 +47,16 @@ Server: mockserver.Fixed{
 
 ## Conditional Mock Server
 
-This mock server returns a 200 status code along with response data (e.g., indicating a job was created) 
-only if the conditions are met. The conditions in this example require that both the URL path and the request 
-body match expected values. If the conditions are not met, an optional Else clause can specify a default response 
+This mock server returns a 200 status code along with response data (e.g., indicating a job was created)
+only if the conditions are met. The conditions in this example require that both the URL path and the request
+body match expected values. If the conditions are not met, an optional Else clause can specify a default response
 (otherwise the server defaults to a 500 status with a failure message).
 This is highly useful to ensure that requests are constructed properly by the connector with respect to provider APIs.
 ```go
 Server: mockserver.Conditional{
 	Setup: mockserver.ContentJSON(),
 	If: mockcond.And{
-		mockcond.PathSuffix("/services/data/v59.0/jobs/ingest"),
+		mockcond.PathSuffix("/services/data/v60.0/jobs/ingest"),
 		mockcond.Body(bodyRequest),
 	},
 	Then: mockserver.Response(http.StatusOK, responseCreateJob),
@@ -66,8 +66,8 @@ Server: mockserver.Conditional{
 
 ## Switch Mock Server
 
-This mock server behaves like a Go switch statement, evaluating multiple cases and returning the response 
-for the first matching condition. In this example, it selects the response based on the request URL path, 
+This mock server behaves like a Go switch statement, evaluating multiple cases and returning the response
+for the first matching condition. In this example, it selects the response based on the request URL path,
 with a default response if no cases match.
 This is particularly useful when a connector makes multiple API calls, each requiring a different response.