I'm trying to execute an SOQL query via REST API call because I want to retrieve custom labels (ExternalString) previous to a date and by Category.

I generate my query like this

Datetime limitDate = Datetime.now();
String query = 'SELECT Name FROM ExternalString WHERE Category = \'Test\' AND LastModifiedDate >= ' + limitDate;

And I'm trying this request

endpoint = '/services/data/v' + apiversion + '/query/q=' + EncodingUtil.urlEncode(query.replace(' ','+'), 'UTF-8');
HttpResponse result;
Http http = new Http();
HttpRequest req = new HttpRequest();
result = http.send(req);

But it's always giving me the following error:

no protocol: /services/data/v48.0/query/q=SELECT%2BName%2BFROM%2BExternalString%2BWHERE%2BCategory%2B%3D%2B%27App%2BM%C3%B3vil%27%2BAND%2BLastModifiedDate%2B%3E%3D%2B2021-03-09%2B23%3A00%3A00

Is there something I'm doing wrong or missing when trying to achieve this functionality?

Thanks in advance!

2 Answers 2


There's a couple things that need fixing

  1. You need to use ?q= in your query. See the example below from the REST API developer guide
  1. The object you're querying is only available through the Tooling API as well so you need to use that endpoint
  1. The date value you're using in your filter needs to be in the following format 2021-03-09T00:00:00z
  1. You need to pass a session Id in the Authorization header. See REST Headers or look at @sfdcfox's tip for using PageReference to avoid needing this snippet
req.setHeader('Content-Type', 'application/json');
req.setHeader('Accept', 'application/json');
req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
  • I'm trying but still gives me the no protocol error. This is the endpoint I'm generating: /services/data/v48.0/query/?q=SELECT+Name+FROM+ExternalString+WHERE+Category+=+'App+Móvil'+AND+LastModifiedDate+>=+'2021-03-09+23:00:00'
    – molinet
    Mar 16, 2021 at 15:14
  • there's actually a couple things I missed - updated answer with the issues I noticed. Was able to query testing in REST explorer in workbench. Mar 16, 2021 at 15:21
  • Thanks! But now it's giving me [{"message":"Session expired or invalid","errorCode":"INVALID_SESSION_ID"}] even though I try the '/services' in workbench and works fine...
    – molinet
    Mar 16, 2021 at 15:56
  • That's to do with the fact you're not passing any session ID which workbench is handling for you. You can click on "Headers" in workbench and see which ones are required . I edited the answer to include this info. Mar 16, 2021 at 16:05
  • 1
    @molinet req.setHeader('Authorization','Bearer '+ UserInfo.getSessionId())
    – sfdcfox
    Mar 16, 2021 at 18:29

You need to specify a full URL, as in:

String endpoint = 'https://mydomain.my.salesforce.com/services/data/...';

If you want to call the local Salesforce server, you can use a PageReference:

PageReference ref = new PageReference('/services/data/...');
Blob result = ref.getContent();

The advantage of this approach is that you don't need to specify the authorization header, etc.

  • I'm trying now but it's giving me a [{"message":"Session expired or invalid","errorCode":"INVALID_SESSION_ID"}] but if I pick my endpoint from /services and on it works properly. I'm generating the endpoint with URL.getSalesforceBaseUrl().toExternalForm() + ''/services...' and setting the method as GET. Do I need anything else?
    – molinet
    Mar 16, 2021 at 15:51
  • @molinet If you use HttpRequest, you need to req.setHeader('Authorization','Bearer '+UserInfo.getSessionId());
    – sfdcfox
    Mar 16, 2021 at 17:20
  • 1
    @molinet Also, why not just use PageReference? Saves you the trouble of using session Id.
    – sfdcfox
    Mar 16, 2021 at 18:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .