Thursday, August 6, 2026

Salesforce REST API: Upload a Files to a Record Attachments | Step-by-Step Guide

Uploading a file to a Salesforce record using the REST API is a straightforward process. In this tutorial, I'll walk you through the complete process using only four cURL commands.

The entire process consists of four simple steps:

  1. Authenticate with your Salesforce org to obtain an Access Token.

  2. Upload the file from your local machine to Salesforce using the Access Token. This request returns the ContentVersion Id.

  3. Retrieve the ContentDocument Id using the ContentVersion Id.

  4. Link the file to a Salesforce record using the ContentDocument Id.

That's it! With these four REST API calls, your file will be successfully attached to the desired Salesforce record.


What is cURL?

cURL (Client URL) is a command-line tool used to send HTTP requests to web servers and REST APIs. It is one of the most widely used tools for testing and interacting with REST services, including the Salesforce REST API.

Throughout this tutorial, we'll use only 4 cURL commands to perform all the API requests.


Do You Need to Install cURL?

Whether you need to install cURL depends on your operating system.

Operating SystemIs cURL Pre-installed?
Windows 10 (Version 1803+) & Windows 11✅ Yes
Linux✅ Usually Pre-installed
macOS✅ Yes
Windows 7 / Windows 8❌ Usually Not Installed

How to Check Whether cURL is Installed

Open Command Prompt or PowerShell and execute the following command:

curl --version

If installed, you'll see output with it's version and if it is not there then you will get message like "'curl' is not recognized as an internal or external command".

Note: This tutorial assumes that cURL is already installed and available on your machine.


Let's Get Started

Now that we have a basic understanding of cURL, let's dive into the implementation.

In the following sections, we'll go through each of the four REST API calls required to upload a file and attach it to a Salesforce record, with complete request examples and explanations for each step.


Step 1: Authenticate with Your Salesforce Org and Obtain an Access Token

Open Command Prompt (Windows) and execute the following cURL command to authenticate with your Salesforce org.






Note:
The cURL command shown in the above article may be split across multiple lines for better readability. Before executing it in Command Prompt, remove the trailing backslash (\) from the end of each line and combine the entire command into a single line.


Below is the Raw Command I used for my testing,

curl -X POST https://login.salesforce.com/services/oauth2/token -d "grant_type=password" -d "client_id=AKHG9d8..z.hDcPKzY60RcaEIAGFHl9AfckqHkoY.y3AHazraPEaiwu3LbM7YVh9wi4ap" -d "client_secret=C7B12F5AKH21642AA58B29F7E540F0722E5AE83915275" -d "username=arunkumar@hazra.com" -d "password=Abc@1234bMAKHAcBHH8vZCtM6dZD"


Response I received:
{"access_token":"00D7F0000LOVEAQN_u.PIqS6AKHfR2ZTtjk8QmBOEn56A7i1tcPshZOWHi5xReHVDR73m6dUMeyiIyDF43DWsW5CY","instance_url":"https://lwcdmn-dev-ed.my.salesforce.com","id":"https://login.salesforce.com/id/00D7F000000saHDUAY/0057F000000xxXnQAI","token_type":"Bearer","issued_at":"1786011844436","signature":"tPvyF5HRbTUNv1w3rBqQe+FjkIk1/o6Q8sogmUrzboI="}


Note:
This highlighted Access Token, we will use in our next steps (Step-2)

Step 2:Upload the file from your local machine to Salesforce using the Access Token. This request returns the ContentVersion Id.

Open Command Prompt (Windows) and execute the following cURL command to upload the file in Salesforce as a ContentVersion and then as a response collect the ContenVersion Id.








Note:
The cURL command shown in the above article may be split across multiple lines for better readability. Before executing it in Command Prompt, remove the trailing backslash (\) from the end of each line and combine the entire command into a single line.

Below is the Raw Command I used for my testing,

curl --request POST "https://lwcdmn-dev-ed.my.salesforce.com/services/data/v55.0/sobjects/ContentVersion" --header "Authorization: Bearer 00D7F0000LOVEAQN_u.PIqS6AKHfR2ZTtjk8QmBOEn56A7i1tcPshZOWHi5xReHVDR73m6dUMeyiIyDF43DWsW5CY" --form "entity_content={\"Title\":\"MediAssistCard\",\"PathOnClient\":\"MediAssistCard.pdf\"};type=application/json" --form "VersionData=@C:\Arun\MediAssistCard.pdf;type=application/octet-stream"

Response I received:
Response: {"id":"068NS00000aABC7YAO","success":true,"errors":[]}


Note:

  •  This highlighted ContentVersion Id in GREEN, we will use in our next steps (Step-3).
  • VVI:  Please notice the highlighted parpel color in my raw command, this is very very important note. If you are using a quote under another quote then use this backslash (\) before each quote which are part under a parent quotes. If you did a single mistake on syntax then it will be very hard to solve. So, be carefull on this command systax.
  • VVI: Try to use  absolute path of your file location like I mentioned in ORANGE colour and keep your folder name without space.


Step 3: Retrieve the ContentDocument Id using the ContentVersion Id.

Open Command Prompt (Windows) and execute the following cURL command to get the ContentDocument Id by using the Content Version Id (068NS00000aABC7YAO) that we have received from Step-2 response.






Note:
The cURL command shown in the above article may be split across multiple lines for better readability. Before executing it in Command Prompt, remove the trailing backslash (\) from the end of each line and combine the entire command into a single line.

Below is the Raw Command I used for my testing,

curl -X GET https://lwcdmn-dev-ed.my.salesforce.com/services/data/v55.0/sobjects/ContentVersion/068NS00000aABC7YAO -H "Authorization: Bearer 00D7F0000LOVEAQN_u.PIqS6AKHfR2ZTtjk8QmBOEn56A7i1tcPshZOWHi5xReHVDR73m6dUMeyiIyDF43DWsW5CY" -H "Content-Type: application/json"

Response I received:
{"attributes":{"type":"ContentVersion","url":"/services/data/v55.0/sobjects/ContentVersion/068NS00000aECJ7YAO"},"Id":"068NS00000aABC7YAO","ContentDocumentId":"069NS00000czFmRYAU","IsLatest":true,"ContentUrl":null,"ContentBodyId":"05TNS000066DRgK2AW","VersionNumber":"1","Title":"MediAssistCard","Description":null,"ReasonForChange":null,"SharingOption":"A","SharingPrivacy":"N","PathOnClient":"MediAssistCard.pdf","RatingCount":0,"IsDeleted":false,"ContentModifiedDate":"2026-08-06T10:26:01.000+0000","ContentModifiedById":"0057F087800xxXnQAI","PositiveRatingCount":0,"NegativeRatingCount":0,"FeaturedContentBoost":null,"FeaturedContentDate":null,"OwnerId":"0057F000000xxXnQAI","CreatedById":"0057F009870xxXnQAI","CreatedDate":"2026-08-06T10:26:01.000+0000","LastModifiedById":"0057F008780xxXnQAI","LastModifiedDate":"2026-08-06T10:26:01.000+0000","SystemModstamp":"2026-08-06T10:26:03.000+0000","TagCsv":null,"FileType":"PDF","PublishStatus":"R","VersionData":"/services/data/v55.0/sobjects/ContentVersion/068NS00999aECJ7YAO/VersionData","ContentSize":527093,"FileExtension":"pdf","FirstPublishLocationId":"0057F009990xxXnQAI","Origin":"C","ContentLocation":"S","TextPreview":null,"ExternalDocumentInfo1":null,"ExternalDocumentInfo2":null,"ExternalDataSourceId":null,"Checksum":"97ee0e4c74d7be1drtet45b0c693b0ae","IsMajorVersion":true,"IsAssetEnabled":false}


Note:

  •  This highlighted ContentDocumentId in GREEN, we will use in our next steps (Step-4).

Step 4: Link the file to a Salesforce record using the ContentDocument Id.

Now this is the final steps where we will atach the file to a Salesfroce Record. For my example I am going to load this file under one Account Record. So, before execute this commnad, lets check the Salesforce Account Record and we could see no file attached at this moment.


 

 




Open Command Prompt (Windows) and execute the following cURL command to attache the file to the Account Record (0017F000007A2eZQAS) by using the ContentDocumentId (069NS00000czFmRYAU) that we have received from Step-3 response.







Below is the Raw Command I used for my testing,

curl -X POST https://lwcdmn-dev-ed.my.salesforce.com/services/data/v55.0/sobjects/ContentDocumentLink -H "Authorization: Bearer 00D7F000000saHD!AQEAQN_u.PIqS6kPhfinZG49wp3AYsp7IBfR2ZTtjk8QmBOEn56A7i1tcPshZOWHi5xReHVDR73m6dUMeyiIyDF43DWsW5CY" -H "Content-Type: application/json" -d "{\"ContentDocumentId\" : \"069NS00000czFmRYAU\",\"LinkedEntityId\" : \"0017F000007A2eZQAS\",\"ShareType\" : \"V\",\"Visibility\" : \"AllUsers\"}"

Response I received:

{"id":"06ANS00000XYZUb2AL","success":true,"errors":[]}


After successfull completion of above step-4, if we check our Salesfroce record then we will file the respective file will be attached under the mentioned record (for our case Account Record),










Final Note:

1. Use the above 4 raw commnads I have used and just change the parameters value as per user setup.
2. You can load a large file. FYI I have tested for a video file with size of 85 MB and it has attached successfully.
3. In Step-4 we use 2 things, "ShareType" and "Visibility", so you can check the below details for this 2 parameters and set it as per your need.



Sunday, June 18, 2023

LWC to LWC Communication using Lightning Messaging Service (Part - 2)

In my previous post (previous post link) we have learn how to create a Lightning Messaging Service with 6 steps and today we will use the same Lightning Messaging Service to communicate between 2 LWC components.


Solution:

Step-1: 

Create 2 LWC components "myLWCOne" and "myLWCTwo" from your VS Code Editor.

Step-2: 

Update the package.xml under manifest folder with below code, here I have added two newly created LWC components under "LightningComponentBundle".

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>myLWCOne</members>
        <members>myLWCTwo</members>
        <name>LightningComponentBundle</name>
    </types>
    <types>
       <members>*</members>
       <name>LightningMessageChannel</name>
    </types>
    <version>57.0</version>
</Package>


Step-3: 

Below are the "myLWCOne" lightning component codebase,

myLWCOne.html
<template>
    <lightning-card  title="LWC One Component">
        <div class="slds-var-p-around_medium lgc-bg">
            <lightning-input type="text"
            label="Enter some messge to Publish" onkeyup={handleKeyUp}>
            </lightning-input>
        </div>

        <div class="slds-p-around_medium lgc-bg">
            <lightning-button label="Publish" onclick={handlePublishMessage}>
            </lightning-button>
        </div>
    </lightning-card>
</template>

myLWCOne.js
import { LightningElement, wire } from 'lwc';
import demoMsgChannel from "@salesforce/messageChannel/MyLightningMS__c";
import { MessageContext, publish} from 'lightning/messageService';
export default class MyLWCOne extends LightningElement {
    inputVal;
    @wire(MessageContext)
    context;

    handleKeyUp(event){
        this.inputVal = event.target.value;
    }

    handlePublishMessage(){
        const message = {
            //messageToSend is nothing but the fieldName we have created
            //under MYLightningMS Channel
            messageToSend:{
                value:this.inputVal
            }
        }
        // publish(messageContext, messsageChannel, message); <<<< PUBLISH TEMPLATE
        publish(this.context, demoMsgChannel, message);
    }
}

myLWCOne.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>57.0</apiVersion>
    <isExposed>true</isExposed>

    <targets>
        <target>lightning__AppPage</target>
    </targets>
</LightningComponentBundle>


Step-4: 

Below are the "myLWCTwo" lightning component codebase,

myLWCTwo.html
<template>
    <lightning-card  title="LWC Two Component">
        <div class="slds-var-p-around_medium lgc-bg">
            Message Received From Component One is <strong>{receivedMessage}</strong>
        </div>
    </lightning-card>
</template>

myLWCTwo.js
import { LightningElement, wire } from 'lwc';
import demoMsgChannel from "@salesforce/messageChannel/MyLightningMS__c";
import { APPLICATION_SCOPE, MessageContext, subscribe} from 'lightning/messageService';
export default class MyLWCTwo extends LightningElement {
    receivedMessage;
    @wire(MessageContext)
    context;

    //To call the subscribeMessage() method on pageloge we will
    //use connectedCallback() method.
    connectedCallback(){
        this.subscribeMessage();
    }

    subscribeMessage(){
        //subscribe(messageContext, messageChannel, listner, subscriberOption)
        subscribe(this.context, demoMsgChannel,
                    (message)=>{this.handleMessage(message)},
                        {scope:APPLICATION_SCOPE});
    }

    handleMessage(message){
        this.receivedMessage = message.messageToSend.value
                    ? message.messageToSend.value : "No Message Send or Published.";
    }
}

myLWCTwo.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>57.0</apiVersion>
    <isExposed>true</isExposed>

    <targets>
        <target>lightning__AppPage</target>
    </targets>
</LightningComponentBundle>

Step-5: 

Create an App Page and drag these 2 LWC components under it.

And after save and activate this page, search for "Lightning Messaging Service Example" whcih is my App Page as created above screen and then click on it and it will be look like below screen,

Step-6: 

Now it's time to test.

Test-1: Click on "Publish" button without entering any input text under "LWC One Component" and after click on "Publish" button, as no input pass from Component One so it will display below message in "LWC Two Component".

Test-2: Click on "Publish" button after enter some input text under "LWC One Component" and after click on "Publish" button, inputted value will be pass from Component One to Component Two and it will display below message in "LWC Two Component".


Note: Full development details will be share in my YouTube Channel very quickly, so please do subscribe my YouTube Channel YouTube (AKH Coding Class) to get more information like this.


 

LWC to LWC Communication using Lightning Messaging Service (Part - 1)

Scenario: Our aim is to send some message from 2 different LWC Components where there is no Parent Child relationship between them and we will pass this message using Lightning Messaging Service.

After completing this assignment we will execute the below Screen, where in 1st LWC component (LWC One Component) has an Input field and a Submit button named as "Publish".

If user input some value and click on "Publish" button then 2nd LWC component (LWC Two Component) will display the message passed in component one's input filed.



Solution:

Note: In this post I will only focus on how to develop a Lightning Messaging Service. So, assumming, you have a good understanding of how to create Project in VS Code, how to create a LWC component inn VS Code, how to deploy comonent from VS Code to Salesforce ORG etc.

First we will follow below 6 Steps to implement Lightning Messaging Service and then we will apply this LMS with 2 LWC Components:

Step-1: 

Create a Project with Manifest in VS Code. 

For my case the Project name is LIGHTNINGMESSAGINGSERVICE and System will automatically create the below files and folders structures.

Step-2: 

Create a folder named as "messageChannels" under "force-app\main\default". 

Note: folder name should be "messageChannels".

Step-3:

Create a XML file under the above crated "messageChannels" folder and the naming convention of this file should be as mentioed below.
Any_User_Defined_Name.messageChannel-meta.xml

For my case the file name I have given as "MyLightningMS.messageChannel-meta.xml".

Step-4:

Now once your "MyLightningMS.messageChannel-meta.xml" file is ready then please put the below code under this file,
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<LightningMessageChannel xmlns="http://soap.sforce.com/2006/04/metadata">
    <masterLabel>MyMessageChannel</masterLabel>
    <description>This is my first Lightning Message Channel</description>    
    <isExposed>true</isExposed>

    <lightningMessageFields>
       <fieldName>messageToSend</fieldName>
       <description>message To Send</description>
   </lightningMessageFields>
   <!-- We can create multiple fields based on our needs. Below is one example -->
    <lightningMessageFields>
        <fieldName>myLMSData</fieldName>
        <description>Variable used for Lightning Message Service</description>
    </lightningMessageFields>
</LightningMessageChannel>

Step-5:

Now we have to deploy this "MyLightningMS.messageChannel-meta.xml" file to your respective Salesforce Org. So, open the "package.xml" under "manifest" folder.

And now update the package.xml with below lines of code,
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
       <members>*</members>
       <name>LightningMessageChannel</name>
    </types>
    <version>57.0</version>
</Package>

NOTE: Keep in mind your package.xml version should be more than 47. For our case you can see in above screen it is 57.0

Step-6:

Now its time to deply this Message Channel. Authorize your Salesforce from this VS Code Editor and then Deploy this.

Now your Lightning Messaging Service is ready to use. In my next post (LWC to LWC Communication using Lightning Messaging Service (Part - 2), I will use this LMS to communicate between 2 LWCs.

Friday, February 17, 2023

Salesforce and Open AI's GPT-3 (Chat GPT) Integration Sample Apex Code.

 I have implemented a simple use case to communicated between Salesforce and Open AI's GPT-3 (Chat GPT).

Click on the below link to get the full video details,

Salesforce ChatGPT Use Case

Use Case Details:
Lets create a Salesforce Screen where User can see multiple dog breed images in a left panel, which will be dynamically fetch from salesforce record (say the object name is "Dog Breed") and the image will be set in static resource. Now click on any breed image, it's details will be display in right panel.
But, the main aim is that the details will not be collected from any Salesforce Database. It should come from Open AI's GPT-3 (Chat GPT).

Solution:
As solution you have to perform few steps as mentioned below,
1) Create a App Builder name as "Dog Breed" (with Header and Right Side Bar) for above page layout design.
2) Check the "Lightning Page Tab" for above created App Builder (Dog Breed).
3) Create a Lightning Console App (Dog Breed App) and add the above tab as navigation item.
4) Create a "Dog Breed" custom object with 2 fields ,
     i. Name (Capture the Breed Name)
    ii. Image Url (Capture the static resource image location)
5. Create 2 LWC Component
     i. One to show the list of Breed Image (collected from Dog Breed records)
    ii. Two to display the breed details response collected from Open AI's GPT-3
6. Set Remote Site Settings in Salesforce Org (https://api.openai.com).
7. Create an account on Open AI (Signup link: https://openai.com/api/).

8. Login to Open AI and go to the below link 
https://platform.openai.com/docs/quickstart/build-your-application
and scroll down to below section to create your Secret Key,















Note:
1. In this example, I am not going to show you how to create and design the above 2 LWC component, but I am going to share how to connect with Open AI's GPT-3 to take the response (dog breed details).

2. Also as I just did the R&D to communicate between Salesforce and Open AI - so, I am just trying to concentrate on the code how to connect with these two platform, but you can modify the code base by following best practice.

So, here is your Webservice call sample code,

public with sharing class ChatGPTConnectHelper {
    static String END_POINT = 'https://api.openai.com/v1/completions';
    // Pass the breedName parameter's value from UI level, once user clicks on any breed image.
    public static String getChatGPTResponse(String breedName){
        try{
            HttpRequest request = new HttpRequest();

            request.setEndpoint(END_POINT);
            request.setMethod('POST');
            //Use Secreate Key
            request.setHeader('Authorization', 'Bearer '+String.escapeSingleQuotes('Put Your Secret Key').trim());
            request.setTimeout(120000);
            request.setHeader('Content-Type', 'application/json;charset=UTF-8');
           
            String reqQuery = 'Give me ' + breedName + ' Dog Breed Details';
            String reqBody = '{"model": "text-davinci-003","prompt":"'
                +reqQuery+
                '","max_tokens": 4000,"temperature": 0.5,'
                +'"stream": false,"top_p": 1}';
            request.setBody(reqBody);

            Http http = new Http();
            HttpResponse response = http.send(request);          
            //return response.getBody();
            //TODO: Instead below code use proper JSON Formatting to collect the breed details.

            // For simplicity I am using the below formatting.
            String result = String.valueOf( JSON.deserializeUntyped(response.getBody()) );
            Integer firstInd = result.indexOf('text');
            Integer lstInd = result.indexOf('created');
            result = result.substring(firstInd+5, lstInd-4);
            return result;
        } catch(System.CalloutException e){
          System.debug('Sorry, You have an error ' + e.getMessage());
        }
        return null;
    }
}

Click on the blow link to check what is ChatGPT and how to create an account:

ChatGPT Quick Overview

How to create a ChatGPT Account

Sunday, January 1, 2023

Create a Program to Find Armstrong Number | Java While Loop | Class#34

Click on the below link to check the video 👇

Java Class-34
 

Check the YouTube Description for more high level theory details and assignment if design for this video.

If you love this then please don't forget to Like, Share and Subscribe my YouTube Channel.

Friday, December 2, 2022

Print a Number in Reserve Order | Java While Loop | Flow Chart | Class#33

 

Click on the below link to check the video 👇

Java Class-33

Check the YouTube Description for more high level theory details and assignment if design for this video.

If you love this then please don't forget to Like, Share and Subscribe my YouTube Channel.

Calculate Sum of Digits of a Given Number | Java While Loop | Class#32

Click on the below link to check the video 👇

Java Class-32

Check the YouTube Description for more high level theory details and assignment if design for this video.

If you love this then please don't forget to Like, Share and Subscribe my YouTube Channel.

 

Salesforce REST API: Upload a Files to a Record Attachments | Step-by-Step Guide

Uploading a file to a Salesforce record using the REST API is a straightforward process. In this tutorial, I'll walk you through the com...