Expensify.org is accepting proposals for new campaigns. Submit yours here by April 30th to receive up to $100,000 in funding for campaigns dismantling injustice related to: Climate, Homes, Hunger, Reentry, or Youth.

API with Python

mikecaputozimikecaputozi Expensify Customer Posts: 3 Expensify Newcomer

I'm trying to build an integration to update employees' managers using the Expensify API with Python. I need to know how to attach the CSV file containing the employees to be updated. I see how to do it with curl, but I can't quite figure out how to translate that to Python. Should it be another key in the JSON data? If so, what's the key name?

Here is the Python code I have so far:

import requests as req

import json

import csv

class Expensify:

    apiurl = "https://integrations.expensify.com/Integration-Server/ExpensifyIntegrations"

  user = "..."

  secret = "..."

  policyid = "..."

  def getbasemessage(self, action="update", objecttype="employees") -> dict:

    base = {

      "requestJobDescription": {

        "type": action,

        "credentials": {

          "partnerUserID": self.user,

          "partnerUserSecret": self.secret


        "inputSettings": {

          "type": objecttype,

          "policyID": self.policyid,

          "fileType": "csv"




    return base

  def sendmessage(self, msg):

    result = req.post(self.apiurl, data=json.dumps(msg), headers="Expect:")

    return result

  def usermanagerupdate(self, employeeemail, manageremail):

    msg = self.getbasemessage()

    d = {

      "EmployeeEmail": employeeemail,

      "ManagerEmail": manageremail,

      "Admin": False


    with open("temp.csv", "w") as f:

      w = csv.DictWriter(f, d.keys())



    # How do I get the file in here?




  • mikecaputozimikecaputozi Expensify Customer Posts: 3 Expensify Newcomer

    In case anyone is interested, I was able to figure this out with the help of a colleague. Here is the updated code. Note that the isAdmin function is new but not related to the solution to my original issue; it's there because the Admin field is required but I don't know of a way to query the API to find out if the user is actually an admin. So I had to create a file that lists all existing admins in order to avoid overwriting that property incorrectly.

    import requests as req

    import json

    import csv

    import os

    class Expensify:

        APIURL = "https://integrations.expensify.com/Integration-Server/ExpensifyIntegrations"

        USER = "..."

        SECRET = "..."

        POLICYID = "..."

        TEMPFILE = "temp.csv"

        ADMINFILE = "admins.txt"


        def getbasemessage(self, action="update", objecttype="employees") -> dict:

            base = {

                "type": action,

                "credentials": {

                    "partnerUserID": self.USER,

                    "partnerUserSecret": self.SECRET


                "inputSettings": {

                    "type": objecttype,

                    "policyID": self.POLICYID,

                    "fileType": "csv"



            return base


        def sendmessage(self, msg):

            output = []

            data = {

                "requestJobDescription": json.dumps(msg, indent=4),


            files = {

                "data": (self.TEMPFILE, open(self.TEMPFILE, "r")),


            result = req.post(self.APIURL, data=data, files=files, timeout=60)


            return result


        def employeemanagerupdate(self, employeeemail, manageremail):

            msg = self.getbasemessage()

            d = {

                "EmployeeEmail": employeeemail,

                "ManagerEmail": manageremail,

                "Admin": self.isAdmin(employeeemail)


            with open(self.TEMPFILE, "w", newline="") as f:

                w = csv.DictWriter(f, d.keys())




            result = self.sendmessage(msg)



            return result


        def isAdmin(self, email) -> bool:

            with open(self.ADMINFILE, "r") as a:

                admins = a.readlines()


            admin = False

            if email in admins:

                admin = True


            return admin

Sign In or Register to comment.