Answers.Body: <p>You have to use Attachments, which is only available in API 3. See <a href="https://civicrm.stackexchange.com/questions/28754/get-url-of-custom-image-field">previous question</a> here.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-07-03T08:50:55.633Z
Answers.Text: Thank you for your prompt response, but I have tried this url and it does not work `https://members.wfto.com/civicrm/custom/orgchart.jpg` . Could this be a permissions issue?
Answers.UserDisplayName: Evan Taylor
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-07-03T14:02:24.230Z
Answers.Text: Have you double checked that URL is correct with one of the images within CiviCRM?
Answers.UserDisplayName: Lars SG
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-07-03T14:02:39.823Z
Answers.Text: Alternatively, there is an extension that exports all of these: https://civicrm.org/extensions/exportphotos
Answers.UserDisplayName: Lars SG
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-07-04T09:24:45.260Z
Answers.Text: Sadly, that solution isn't what my client wants. They expect a json file output with image url's. That json file will be used to import data into a wordpress site. in the beginning of the project I was able to use this url: `https://members.wfto.com/civicrm/file/imagefile/10-10.png` . The client has made changes to the CRM and now that url doesn't work anymore. The client has said they have reverted changes but I'm still not able to use this url. That's why I am searching for an alternative.
Answers.UserDisplayName: Evan Taylor
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-07-04T14:23:33.813Z
Answers.Text: Did you see this question? I think it answers what you're looking for.
  https://civicrm.stackexchange.com/questions/28754/get-url-of-custom-image-field
Answers.UserDisplayName: Lars SG
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-07-05T18:25:50.240Z
Answers.Text: I've changed my answer above as I realized it was incorrect. Sorry!
Answers.UserDisplayName: Lars SG
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-07-17T09:53:40.537Z
Answers.Text: Sorry for the late response. I have done some research and have found out that, there is an endpoint in API 3 that get's me exactly what I want. The "DownloadLinks" API end point sends back exactly what is needed when I use the API explorer on the back end. But I'm having difficulty actually calling the endpoint from Postman or my Python script. I have the correct API key and secret key. Not quite sure why this is happening.
Answers.UserDisplayName: Evan Taylor
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-06-30T20:04:06.473Z
Answers.LastActivityDate: 2023-07-05T18:25:30.107Z
Answers.LastEditDate: 2023-07-05T18:25:30.107Z
Answers.UserDisplayName: Lars SG
Body: <p>I am creating a Python script that retrieves images from CiviCRM. I don't just want the image name (which I retrieve with the uri field already) but the entire image url. How is that possible? I have tried the this (<a href="https://civicrm.stackexchange.com/questions/17208/how-to-retrieve-contact-image-url-in-civicrm-with-the-api">How to retrieve contact image URL in CiviCRM with the API</a>) and that didn't give me the result I was looking for. please see code below:</p>
  <pre><code>import requests
  import json
  import os
  import time
  from util import *
  
  
  server_time = datetime.datetime.now()
  directory = os.environ.get('LOCAL_DIRECTORY')
  
  
  def main():
      def image_response(mime):
          url = 'https://members.MY_CIVI_CRM_SITE.com/civicrm/ajax/api4/File/get'
          params = {
              'select': [
                  'id',
                  'mime_type',
                  'uri',
              ], 'where': [['mime_type', '=', f'image/{mime}']],
              'limit': 100
          }
          headers = {
              'Content-Type': 'application/x-www-form-urlencoded',
              'X-Civi-Auth': 'Bearer MYBEARERTOKEN'
          }
  
          all_contacts = []
  
          # Retrieve data in batches of 100 using pagination
          offset = 0
          total_contacts = 0
          while True:
              try:
                  params['offset'] = offset
                  data = {'params': json.dumps(params)}
                  response = requests.post(url, headers=headers, data=data)
                  content = response.text
  
                  contacts = json.loads(content)['values']
                  all_contacts.extend(contacts)
  
                  # Update progress and break the loop if the retrieved contacts are less than the limit (i.e., the last batch)
                  num_retrieved = len(contacts)
                  total_contacts += num_retrieved
                  print(
                      f&quot;Retrieved {num_retrieved} images. Total images: {total_contacts}&quot;)
  
                  if num_retrieved &lt; params['limit']:
                      break
  
                  offset += params['limit']
              except requests.exceptions.HTTPError as err:
                  exception_message = f'HTTP error occurred: {err}'
                  log_function(exception_message)
                  time.sleep(30)
                  # Continue with the next iteration of the loop
                  
              except requests.exceptions.RequestException as err:
                  exception_message = f'An error occurred during the request: {err}'
                  log_function(exception_message)
                  time.sleep(30)
                  # Continue with the next iteration of the loop
                  
              except Exception as err:
                  exception_message = f'An exception error occurred during the request: {err}'
                  log_function(exception_message)
                  time.sleep(30)
                  # Continue with the next iteration of the loop
              
  
          return all_contacts
  
      jpeg_images = image_response('jpeg')
      png_images = image_response('png')
  
      all_images = jpeg_images + png_images
  
      # Save contacts to a JSON file
      with open(f'{directory}/image_list.json', 'w') as file:
          json.dump(all_images, file, indent=4)
      message = &quot;All images retrieved and saved to image_list.json&quot;
      print(message)
  
      script_finish_time = datetime.datetime.now() - server_time
      script_finish_time_split = str(script_finish_time).split('.')
      script_complete_message = f'Script completed in {script_finish_time_split[0]}'
      print(script_complete_message)
  
      print(&quot;Phone numbers saved to image_list.json.&quot;)
  
  
  if __name__ == &quot;__main__&quot;:
      main()```
  </code></pre>
  
Tags: <civievent><civicontribute><civimember><webform-civicrm><civireport>
Title: CIVI CRM APIv4 Image retrieval
ThreadText: # CIVI CRM APIv4 Image retrieval
  
  (Asked by: username_0 on 2023-06-30)
  
  I am creating a Python script that retrieves images from CiviCRM. I don't just want the image name (which I retrieve with the uri field already) but the entire image url. How is that possible? I have tried the this (How to retrieve contact image URL in CiviCRM with the API) and that didn't give me the result I was looking for. please see code below:
  import requests
  import json
  import os
  import time
  from util import *
  
  
  server_time = datetime.datetime.now()
  directory = os.environ.get('LOCAL_DIRECTORY')
  
  
  def main():
      def image_response(mime):
          url = 'https://members.MY_CIVI_CRM_SITE.com/civicrm/ajax/api4/File/get'
          params = {
              'select': [
                  'id',
                  'mime_type',
                  'uri',
              ], 'where': [['mime_type', '=', f'image/{mime}']],
              'limit': 100
          }
          headers = {
              'Content-Type': 'application/x-www-form-urlencoded',
              'X-Civi-Auth': 'Bearer MYBEARERTOKEN'
          }
  
          all_contacts = []
  
          # Retrieve data in batches of 100 using pagination
          offset = 0
          total_contacts = 0
          while True:
              try:
                  params['offset'] = offset
                  data = {'params': json.dumps(params)}
                  response = requests.post(url, headers=headers, data=data)
                  content = response.text
  
                  contacts = json.loads(content)['values']
                  all_contacts.extend(contacts)
  
                  # Update progress and break the loop if the retrieved contacts are less than the limit (i.e., the last batch)
                  num_retrieved = len(contacts)
                  total_contacts += num_retrieved
                  print(
                      f"Retrieved {num_retrieved} images. Total images: {total_contacts}")
  
                  if num_retrieved < params['limit']:
                      break
  
                  offset += params['limit']
              except requests.exceptions.HTTPError as err:
                  exception_message = f'HTTP error occurred: {err}'
                  log_function(exception_message)
                  time.sleep(30)
                  # Continue with the next iteration of the loop
                  
              except requests.exceptions.RequestException as err:
                  exception_message = f'An error occurred during the request: {err}'
                  log_function(exception_message)
                  time.sleep(30)
                  # Continue with the next iteration of the loop
                  
              except Exception as err:
                  exception_message = f'An exception error occurred during the request: {err}'
                  log_function(exception_message)
                  time.sleep(30)
                  # Continue with the next iteration of the loop
              
  
          return all_contacts
  
      jpeg_images = image_response('jpeg')
      png_images = image_response('png')
  
      all_images = jpeg_images + png_images
  
      # Save contacts to a JSON file
      with open(f'{directory}/image_list.json', 'w') as file:
          json.dump(all_images, file, indent=4)
      message = "All images retrieved and saved to image_list.json"
      print(message)
  
      script_finish_time = datetime.datetime.now() - server_time
      script_finish_time_split = str(script_finish_time).split('.')
      script_complete_message = f'Script completed in {script_finish_time_split[0]}'
      print(script_complete_message)
  
      print("Phone numbers saved to image_list.json.")
  
  
  if __name__ == "__main__":
      main()```
  
  **Tags:** civievent, civicontribute, civimember, webform-civicrm, civireport
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2023-06-30. Score: 0
  
  You have to use Attachments, which is only available in API 3. See [previous question](https://civicrm.stackexchange.com/questions/28754/get-url-of-custom-image-field) here.
  
  > **Comments:**
  > **username_0**: Thank you for your prompt response, but I have tried this url and it does not work `https://members.wfto.com/civicrm/custom/orgchart.jpg` . Could this be a permissions issue?  
  > **username_1**: Have you double checked that URL is correct with one of the images within CiviCRM?  
  > **username_1**: Alternatively, there is an extension that exports all of these: https://civicrm.org/extensions/exportphotos  
  > **username_0**: Sadly, that solution isn't what my client wants. They expect a json file output with image url's. That json file will be used to import data into a wordpress site. in the beginning of the project I was able to use this url: `https://members.wfto.com/civicrm/file/imagefile/10-10.png` . The client has made changes to the CRM and now that url doesn't work anymore. The client has said they have reverted changes but I'm still not able to use this url. That's why I am searching for an alternative.  
  > **username_1**: Did you see this question? I think it answers what you're looking for. https://civicrm.stackexchange.com/questions/28754/get-url-of-custom-image-field  
  > **username_1**: I've changed my answer above as I realized it was incorrect. Sorry!  
  > **username_0**: Sorry for the late response. I have done some research and have found out that, there is an endpoint in API 3 that get's me exactly what I want. The "DownloadLinks" API end point sends back exactly what is needed when I use the API explorer on the back end. But I'm having difficulty actually calling the endpoint from Postman or my Python script. I have the correct API key and secret key. Not quite sure why this is happening.  
  
  ---
  
  