diff --git a/lib/actions/activity-actions.js b/lib/actions/activity-actions.js
--- a/lib/actions/activity-actions.js
+++ b/lib/actions/activity-actions.js
@@ -7,7 +7,7 @@
   SetThreadUnreadStatusRequest,
   SetThreadUnreadStatusResult,
 } from '../types/activity-types';
-import type { FetchJSON } from '../utils/fetch-json';
+import type { CallServerEndpoint } from '../utils/call-server-endpoint';
 
 const updateActivityActionTypes = Object.freeze({
   started: 'UPDATE_ACTIVITY_STARTED',
@@ -15,11 +15,11 @@
   failed: 'UPDATE_ACTIVITY_FAILED',
 });
 const updateActivity = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   activityUpdates: $ReadOnlyArray<ActivityUpdate>,
 ) => Promise<ActivityUpdateSuccessPayload>) => async activityUpdates => {
-  const response = await fetchJSON('update_activity', {
+  const response = await callServerEndpoint('update_activity', {
     updates: activityUpdates,
   });
   return {
@@ -36,11 +36,11 @@
   failed: 'SET_THREAD_UNREAD_STATUS_FAILED',
 });
 const setThreadUnreadStatus = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   request: SetThreadUnreadStatusRequest,
 ) => Promise<SetThreadUnreadStatusPayload>) => async request => {
-  const response: SetThreadUnreadStatusResult = await fetchJSON(
+  const response: SetThreadUnreadStatusResult = await callServerEndpoint(
     'set_thread_unread_status',
     request,
   );
diff --git a/lib/actions/device-actions.js b/lib/actions/device-actions.js
--- a/lib/actions/device-actions.js
+++ b/lib/actions/device-actions.js
@@ -1,7 +1,7 @@
 // @flow
 
+import type { CallServerEndpoint } from '../utils/call-server-endpoint';
 import { getConfig } from '../utils/config';
-import type { FetchJSON } from '../utils/fetch-json';
 
 const setDeviceTokenActionTypes = Object.freeze({
   started: 'SET_DEVICE_TOKEN_STARTED',
@@ -9,9 +9,9 @@
   failed: 'SET_DEVICE_TOKEN_FAILED',
 });
 const setDeviceToken = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((deviceToken: ?string) => Promise<?string>) => async deviceToken => {
-  await fetchJSON('update_device_token', {
+  await callServerEndpoint('update_device_token', {
     deviceToken,
     platformDetails: getConfig().platformDetails,
   });
diff --git a/lib/actions/entry-actions.js b/lib/actions/entry-actions.js
--- a/lib/actions/entry-actions.js
+++ b/lib/actions/entry-actions.js
@@ -16,8 +16,8 @@
   CalendarQueryUpdateResult,
 } from '../types/entry-types';
 import type { HistoryRevisionInfo } from '../types/history-types';
+import type { CallServerEndpoint } from '../utils/call-server-endpoint';
 import { dateFromString } from '../utils/date-utils';
-import type { FetchJSON } from '../utils/fetch-json';
 
 const fetchEntriesActionTypes = Object.freeze({
   started: 'FETCH_ENTRIES_STARTED',
@@ -25,11 +25,11 @@
   failed: 'FETCH_ENTRIES_FAILED',
 });
 const fetchEntries = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   calendarQuery: CalendarQuery,
 ) => Promise<FetchEntryInfosResult>) => async calendarQuery => {
-  const response = await fetchJSON('fetch_entries', calendarQuery);
+  const response = await callServerEndpoint('fetch_entries', calendarQuery);
   return {
     rawEntryInfos: response.rawEntryInfos,
   };
@@ -41,7 +41,7 @@
   failed: 'UPDATE_CALENDAR_QUERY_FAILED',
 });
 const updateCalendarQuery = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   calendarQuery: CalendarQuery,
   reduxAlreadyUpdated?: boolean,
@@ -49,7 +49,10 @@
   calendarQuery,
   reduxAlreadyUpdated = false,
 ) => {
-  const response = await fetchJSON('update_calendar_query', calendarQuery);
+  const response = await callServerEndpoint(
+    'update_calendar_query',
+    calendarQuery,
+  );
   const { rawEntryInfos, deletedEntryIDs } = response;
   return {
     rawEntryInfos,
@@ -87,11 +90,11 @@
   failed: 'CREATE_ENTRY_FAILED',
 });
 const createEntry = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   request: CreateEntryInfo,
 ) => Promise<CreateEntryPayload>) => async request => {
-  const result = await fetchJSON('create_entry', request);
+  const result = await callServerEndpoint('create_entry', request);
   return {
     entryID: result.entryID,
     newMessageInfos: result.newMessageInfos,
@@ -108,9 +111,9 @@
 });
 const concurrentModificationResetActionType = 'CONCURRENT_MODIFICATION_RESET';
 const saveEntry = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((request: SaveEntryInfo) => Promise<SaveEntryResult>) => async request => {
-  const result = await fetchJSON('update_entry', request);
+  const result = await callServerEndpoint('update_entry', request);
   return {
     entryID: result.entryID,
     newMessageInfos: result.newMessageInfos,
@@ -124,9 +127,9 @@
   failed: 'DELETE_ENTRY_FAILED',
 });
 const deleteEntry = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((info: DeleteEntryInfo) => Promise<DeleteEntryResult>) => async info => {
-  const response = await fetchJSON('delete_entry', {
+  const response = await callServerEndpoint('delete_entry', {
     ...info,
     timestamp: Date.now(),
   });
@@ -143,11 +146,13 @@
   failed: 'FETCH_REVISIONS_FOR_ENTRY_FAILED',
 });
 const fetchRevisionsForEntry = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   entryID: string,
 ) => Promise<$ReadOnlyArray<HistoryRevisionInfo>>) => async entryID => {
-  const response = await fetchJSON('fetch_entry_revisions', { id: entryID });
+  const response = await callServerEndpoint('fetch_entry_revisions', {
+    id: entryID,
+  });
   return response.result;
 };
 
@@ -157,9 +162,9 @@
   failed: 'RESTORE_ENTRY_FAILED',
 });
 const restoreEntry = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((info: RestoreEntryInfo) => Promise<RestoreEntryResult>) => async info => {
-  const response = await fetchJSON('restore_entry', {
+  const response = await callServerEndpoint('restore_entry', {
     ...info,
     timestamp: Date.now(),
   });
diff --git a/lib/actions/message-actions.js b/lib/actions/message-actions.js
--- a/lib/actions/message-actions.js
+++ b/lib/actions/message-actions.js
@@ -8,7 +8,10 @@
   SimpleMessagesPayload,
 } from '../types/message-types';
 import type { MediaMessageServerDBContent } from '../types/messages/media.js';
-import type { FetchJSON, FetchResultInfo } from '../utils/fetch-json';
+import type {
+  CallServerEndpoint,
+  CallServerEndpointResultInfo,
+} from '../utils/call-server-endpoint';
 
 const fetchMessagesBeforeCursorActionTypes = Object.freeze({
   started: 'FETCH_MESSAGES_BEFORE_CURSOR_STARTED',
@@ -16,7 +19,7 @@
   failed: 'FETCH_MESSAGES_BEFORE_CURSOR_FAILED',
 });
 const fetchMessagesBeforeCursor = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   threadID: string,
   beforeMessageID: string,
@@ -24,7 +27,7 @@
   threadID,
   beforeMessageID,
 ) => {
-  const response = await fetchJSON('fetch_messages', {
+  const response = await callServerEndpoint('fetch_messages', {
     cursors: {
       [threadID]: beforeMessageID,
     },
@@ -42,11 +45,11 @@
   failed: 'FETCH_MOST_RECENT_MESSAGES_FAILED',
 });
 const fetchMostRecentMessages = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   threadID: string,
 ) => Promise<FetchMessageInfosPayload>) => async threadID => {
-  const response = await fetchJSON('fetch_messages', {
+  const response = await callServerEndpoint('fetch_messages', {
     cursors: {
       [threadID]: null,
     },
@@ -64,14 +67,14 @@
   failed: 'FETCH_SINGLE_MOST_RECENT_MESSAGES_FROM_THREADS_FAILED',
 });
 const fetchSingleMostRecentMessagesFromThreads = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   threadIDs: $ReadOnlyArray<string>,
 ) => Promise<SimpleMessagesPayload>) => async threadIDs => {
   const cursors = Object.fromEntries(
     threadIDs.map(threadID => [threadID, null]),
   );
-  const response = await fetchJSON('fetch_messages', {
+  const response = await callServerEndpoint('fetch_messages', {
     cursors,
     numberPerThread: 1,
   });
@@ -87,17 +90,17 @@
   failed: 'SEND_TEXT_MESSAGE_FAILED',
 });
 const sendTextMessage = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   threadID: string,
   localID: string,
   text: string,
 ) => Promise<SendMessageResult>) => async (threadID, localID, text) => {
   let resultInfo;
-  const getResultInfo = (passedResultInfo: FetchResultInfo) => {
+  const getResultInfo = (passedResultInfo: CallServerEndpointResultInfo) => {
     resultInfo = passedResultInfo;
   };
-  const response = await fetchJSON(
+  const response = await callServerEndpoint(
     'create_text_message',
     {
       threadID,
@@ -109,7 +112,7 @@
   const resultInterface = resultInfo?.interface;
   invariant(
     resultInterface,
-    'getResultInfo not called before fetchJSON resolves',
+    'getResultInfo not called before callServerEndpoint resolves',
   );
   return {
     id: response.newMessageInfo.id,
@@ -126,7 +129,7 @@
   failed: 'SEND_MULTIMEDIA_MESSAGE_FAILED',
 });
 const sendMultimediaMessage = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   threadID: string,
   localID: string,
@@ -137,10 +140,10 @@
   mediaMessageContents,
 ) => {
   let resultInfo;
-  const getResultInfo = (passedResultInfo: FetchResultInfo) => {
+  const getResultInfo = (passedResultInfo: CallServerEndpointResultInfo) => {
     resultInfo = passedResultInfo;
   };
-  const response = await fetchJSON(
+  const response = await callServerEndpoint(
     'create_multimedia_message',
     {
       threadID,
@@ -152,7 +155,7 @@
   const resultInterface = resultInfo?.interface;
   invariant(
     resultInterface,
-    'getResultInfo not called before fetchJSON resolves',
+    'getResultInfo not called before callServerEndpoint resolves',
   );
   return {
     id: response.newMessageInfo.id,
@@ -162,17 +165,17 @@
 };
 
 const legacySendMultimediaMessage = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   threadID: string,
   localID: string,
   mediaIDs: $ReadOnlyArray<string>,
 ) => Promise<SendMessageResult>) => async (threadID, localID, mediaIDs) => {
   let resultInfo;
-  const getResultInfo = (passedResultInfo: FetchResultInfo) => {
+  const getResultInfo = (passedResultInfo: CallServerEndpointResultInfo) => {
     resultInfo = passedResultInfo;
   };
-  const response = await fetchJSON(
+  const response = await callServerEndpoint(
     'create_multimedia_message',
     {
       threadID,
@@ -184,7 +187,7 @@
   const resultInterface = resultInfo?.interface;
   invariant(
     resultInterface,
-    'getResultInfo not called before fetchJSON resolves',
+    'getResultInfo not called before callServerEndpoint resolves',
   );
   return {
     id: response.newMessageInfo.id,
diff --git a/lib/actions/relationship-actions.js b/lib/actions/relationship-actions.js
--- a/lib/actions/relationship-actions.js
+++ b/lib/actions/relationship-actions.js
@@ -4,8 +4,8 @@
   RelationshipRequest,
   RelationshipErrors,
 } from '../types/relationship-types';
+import type { CallServerEndpoint } from '../utils/call-server-endpoint';
 import { ServerError } from '../utils/errors';
-import type { FetchJSON } from '../utils/fetch-json';
 
 const updateRelationshipsActionTypes = Object.freeze({
   started: 'UPDATE_RELATIONSHIPS_STARTED',
@@ -13,11 +13,11 @@
   failed: 'UPDATE_RELATIONSHIPS_FAILED',
 });
 const updateRelationships = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   request: RelationshipRequest,
 ) => Promise<RelationshipErrors>) => async request => {
-  const errors = await fetchJSON('update_relationships', request);
+  const errors = await callServerEndpoint('update_relationships', request);
 
   const { invalid_user, already_friends, user_blocked } = errors;
   if (invalid_user) {
diff --git a/lib/actions/report-actions.js b/lib/actions/report-actions.js
--- a/lib/actions/report-actions.js
+++ b/lib/actions/report-actions.js
@@ -4,20 +4,24 @@
   ClientReportCreationRequest,
   ReportCreationResponse,
 } from '../types/report-types';
-import type { FetchJSON } from '../utils/fetch-json';
+import type { CallServerEndpoint } from '../utils/call-server-endpoint';
 
 const sendReportActionTypes = Object.freeze({
   started: 'SEND_REPORT_STARTED',
   success: 'SEND_REPORT_SUCCESS',
   failed: 'SEND_REPORT_FAILED',
 });
-const fetchJSONOptions = { timeout: 60000 };
+const callServerEndpointOptions = { timeout: 60000 };
 const sendReport = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   request: ClientReportCreationRequest,
 ) => Promise<ReportCreationResponse>) => async request => {
-  const response = await fetchJSON('create_report', request, fetchJSONOptions);
+  const response = await callServerEndpoint(
+    'create_report',
+    request,
+    callServerEndpointOptions,
+  );
   return { id: response.id };
 };
 
@@ -27,11 +31,15 @@
   failed: 'SEND_REPORTS_FAILED',
 });
 const sendReports = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   reports: $ReadOnlyArray<ClientReportCreationRequest>,
 ) => Promise<void>) => async reports => {
-  await fetchJSON('create_reports', { reports }, fetchJSONOptions);
+  await callServerEndpoint(
+    'create_reports',
+    { reports },
+    callServerEndpointOptions,
+  );
 };
 
 const queueReportsActionType = 'QUEUE_REPORTS';
diff --git a/lib/actions/thread-actions.js b/lib/actions/thread-actions.js
--- a/lib/actions/thread-actions.js
+++ b/lib/actions/thread-actions.js
@@ -11,7 +11,7 @@
   ClientThreadJoinRequest,
   ThreadJoinPayload,
 } from '../types/thread-types';
-import type { FetchJSON } from '../utils/fetch-json';
+import type { CallServerEndpoint } from '../utils/call-server-endpoint';
 import { values } from '../utils/objects';
 
 const deleteThreadActionTypes = Object.freeze({
@@ -20,7 +20,7 @@
   failed: 'DELETE_THREAD_FAILED',
 });
 const deleteThread = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   threadID: string,
   currentAccountPassword: string,
@@ -28,7 +28,7 @@
   threadID,
   currentAccountPassword,
 ) => {
-  const response = await fetchJSON('delete_thread', {
+  const response = await callServerEndpoint('delete_thread', {
     threadID,
     accountPassword: currentAccountPassword,
   });
@@ -43,11 +43,11 @@
   failed: 'CHANGE_THREAD_SETTINGS_FAILED',
 });
 const changeThreadSettings = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   request: UpdateThreadRequest,
 ) => Promise<ChangeThreadSettingsPayload>) => async request => {
-  const response = await fetchJSON('update_thread', request);
+  const response = await callServerEndpoint('update_thread', request);
   invariant(
     Object.keys(request.changes).length > 0,
     'No changes provided to changeThreadSettings!',
@@ -65,12 +65,12 @@
   failed: 'REMOVE_USERS_FROM_THREAD_FAILED',
 });
 const removeUsersFromThread = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   threadID: string,
   memberIDs: $ReadOnlyArray<string>,
 ) => Promise<ChangeThreadSettingsPayload>) => async (threadID, memberIDs) => {
-  const response = await fetchJSON('remove_members', {
+  const response = await callServerEndpoint('remove_members', {
     threadID,
     memberIDs,
   });
@@ -87,7 +87,7 @@
   failed: 'CHANGE_THREAD_MEMBER_ROLES_FAILED',
 });
 const changeThreadMemberRoles = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   threadID: string,
   memberIDs: $ReadOnlyArray<string>,
@@ -97,7 +97,7 @@
   memberIDs,
   newRole,
 ) => {
-  const response = await fetchJSON('update_role', {
+  const response = await callServerEndpoint('update_role', {
     threadID,
     memberIDs,
     role: newRole,
@@ -115,11 +115,11 @@
   failed: 'NEW_THREAD_FAILED',
 });
 const newThread = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   request: ClientNewThreadRequest,
 ) => Promise<NewThreadResult>) => async request => {
-  const response = await fetchJSON('create_thread', request);
+  const response = await callServerEndpoint('create_thread', request);
   return {
     newThreadID: response.newThreadID,
     updatesResult: response.updatesResult,
@@ -134,11 +134,11 @@
   failed: 'JOIN_THREAD_FAILED',
 });
 const joinThread = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   request: ClientThreadJoinRequest,
 ) => Promise<ThreadJoinPayload>) => async request => {
-  const response = await fetchJSON('join_thread', request);
+  const response = await callServerEndpoint('join_thread', request);
   const userInfos = values(response.userInfos);
   return {
     updatesResult: response.updatesResult,
@@ -154,9 +154,9 @@
   failed: 'LEAVE_THREAD_FAILED',
 });
 const leaveThread = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((threadID: string) => Promise<LeaveThreadPayload>) => async threadID => {
-  const response = await fetchJSON('leave_thread', { threadID });
+  const response = await callServerEndpoint('leave_thread', { threadID });
   return {
     updatesResult: response.updatesResult,
   };
diff --git a/lib/actions/upload-actions.js b/lib/actions/upload-actions.js
--- a/lib/actions/upload-actions.js
+++ b/lib/actions/upload-actions.js
@@ -2,7 +2,7 @@
 
 import type { Shape } from '../types/core';
 import type { UploadMultimediaResult, Dimensions } from '../types/media-types';
-import type { FetchJSON } from '../utils/fetch-json';
+import type { CallServerEndpoint } from '../utils/call-server-endpoint';
 import type { UploadBlob } from '../utils/upload-blob';
 
 export type MultimediaUploadCallbacks = Shape<{
@@ -13,7 +13,7 @@
 export type MultimediaUploadExtras = Shape<{ ...Dimensions, loop: boolean }>;
 
 const uploadMultimedia = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   multimedia: Object,
   extras: MultimediaUploadExtras,
@@ -38,7 +38,7 @@
     stringExtras.loop = '1';
   }
 
-  const response = await fetchJSON(
+  const response = await callServerEndpoint(
     'upload_multimedia',
     {
       multimedia: [multimedia],
@@ -64,9 +64,9 @@
   'UPDATE_MULTIMEDIA_MESSAGE_MEDIA';
 
 const deleteUpload = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((id: string) => Promise<void>) => async id => {
-  await fetchJSON('delete_upload', { id });
+  await callServerEndpoint('delete_upload', { id });
 };
 
 export {
diff --git a/lib/actions/user-actions.js b/lib/actions/user-actions.js
--- a/lib/actions/user-actions.js
+++ b/lib/actions/user-actions.js
@@ -20,8 +20,8 @@
   SubscriptionUpdateResult,
 } from '../types/subscription-types';
 import type { UserInfo, PasswordUpdate } from '../types/user-types';
+import type { CallServerEndpoint } from '../utils/call-server-endpoint';
 import { getConfig } from '../utils/config';
-import type { FetchJSON } from '../utils/fetch-json';
 import sleep from '../utils/sleep';
 
 const logOutActionTypes = Object.freeze({
@@ -30,14 +30,14 @@
   failed: 'LOG_OUT_FAILED',
 });
 const logOut = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   preRequestUserState: PreRequestUserState,
 ) => Promise<LogOutResult>) => async preRequestUserState => {
   let response = null;
   try {
     response = await Promise.race([
-      fetchJSON('log_out', {}),
+      callServerEndpoint('log_out', {}),
       (async () => {
         await sleep(500);
         throw new Error('log_out took more than 500ms');
@@ -54,12 +54,12 @@
   failed: 'DELETE_ACCOUNT_FAILED',
 });
 const deleteAccount = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   password: string,
   preRequestUserState: PreRequestUserState,
 ) => Promise<LogOutResult>) => async (password, preRequestUserState) => {
-  const response = await fetchJSON('delete_account', { password });
+  const response = await callServerEndpoint('delete_account', { password });
   return { currentUserInfo: response.currentUserInfo, preRequestUserState };
 };
 
@@ -68,19 +68,19 @@
   success: 'REGISTER_SUCCESS',
   failed: 'REGISTER_FAILED',
 });
-const registerFetchJSONOptions = { timeout: 60000 };
+const registerCallServerEndpointOptions = { timeout: 60000 };
 const register = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   registerInfo: RegisterInfo,
 ) => Promise<RegisterResult>) => async registerInfo => {
-  const response = await fetchJSON(
+  const response = await callServerEndpoint(
     'create_account',
     {
       ...registerInfo,
       platformDetails: getConfig().platformDetails,
     },
-    registerFetchJSONOptions,
+    registerCallServerEndpointOptions,
   );
   return {
     currentUserInfo: response.currentUserInfo,
@@ -110,19 +110,19 @@
   success: 'LOG_IN_SUCCESS',
   failed: 'LOG_IN_FAILED',
 });
-const logInFetchJSONOptions = { timeout: 60000 };
+const logInCallServerEndpointOptions = { timeout: 60000 };
 const logIn = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((logInInfo: LogInInfo) => Promise<LogInResult>) => async logInInfo => {
   const watchedIDs = threadWatcher.getWatchedIDs();
-  const response = await fetchJSON(
+  const response = await callServerEndpoint(
     'log_in',
     {
       ...logInInfo,
       watchedIDs,
       platformDetails: getConfig().platformDetails,
     },
-    logInFetchJSONOptions,
+    logInCallServerEndpointOptions,
   );
   const userInfos = mergeUserInfos(
     response.userInfos,
@@ -153,11 +153,11 @@
   failed: 'CHANGE_USER_PASSWORD_FAILED',
 });
 const changeUserPassword = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   passwordUpdate: PasswordUpdate,
 ) => Promise<void>) => async passwordUpdate => {
-  await fetchJSON('update_account', passwordUpdate);
+  await callServerEndpoint('update_account', passwordUpdate);
 };
 
 const searchUsersActionTypes = Object.freeze({
@@ -166,11 +166,13 @@
   failed: 'SEARCH_USERS_FAILED',
 });
 const searchUsers = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   usernamePrefix: string,
 ) => Promise<UserSearchResult>) => async usernamePrefix => {
-  const response = await fetchJSON('search_users', { prefix: usernamePrefix });
+  const response = await callServerEndpoint('search_users', {
+    prefix: usernamePrefix,
+  });
   return {
     userInfos: response.userInfos,
   };
@@ -182,11 +184,11 @@
   failed: 'UPDATE_SUBSCRIPTION_FAILED',
 });
 const updateSubscription = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   subscriptionUpdate: SubscriptionUpdateRequest,
 ) => Promise<SubscriptionUpdateResult>) => async subscriptionUpdate => {
-  const response = await fetchJSON(
+  const response = await callServerEndpoint(
     'update_user_subscription',
     subscriptionUpdate,
   );
@@ -203,19 +205,19 @@
 });
 
 const setUserSettings = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   userSettingsRequest: UpdateUserSettingsRequest,
 ) => Promise<void>) => async userSettingsRequest => {
-  await fetchJSON('update_user_settings', userSettingsRequest);
+  await callServerEndpoint('update_user_settings', userSettingsRequest);
 };
 
 const getSessionPublicKeys = (
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
 ): ((
   data: GetSessionPublicKeysArgs,
 ) => Promise<SessionPublicKeys | null>) => async data => {
-  return await fetchJSON('get_session_public_keys', data);
+  return await callServerEndpoint('get_session_public_keys', data);
 };
 
 export {
diff --git a/lib/shared/timeouts.js b/lib/shared/timeouts.js
--- a/lib/shared/timeouts.js
+++ b/lib/shared/timeouts.js
@@ -17,9 +17,10 @@
 // unlikely, as the connectivity issue is likely on the client side.
 export const clientRequestSocketTimeout = 10000; // in milliseconds
 
-// Time after which FetchJSON will timeout a request. When using sockets this is
-// preempted by the above timeout, so it really only applies for HTTP requests.
-export const fetchJSONTimeout = 10000; // in milliseconds
+// Time after which CallServerEndpoint will timeout a request. When using
+// sockets this is preempted by the above timeout, so it really only applies
+// for HTTP requests.
+export const callServerEndpointTimeout = 10000; // in milliseconds
 
 // The server expects to get a request at least every three
 // seconds from the client. If server doesn't get a request
diff --git a/lib/types/message-types.js b/lib/types/message-types.js
--- a/lib/types/message-types.js
+++ b/lib/types/message-types.js
@@ -2,7 +2,7 @@
 
 import invariant from 'invariant';
 
-import type { FetchResultInfoInterface } from '../utils/fetch-json';
+import type { CallServerEndpointResultInfoInterface } from '../utils/call-server-endpoint';
 import { type ClientDBMediaInfo } from './media-types';
 import type {
   AddMembersMessageData,
@@ -485,14 +485,14 @@
 export type SendMessageResult = {
   +id: string,
   +time: number,
-  +interface: FetchResultInfoInterface,
+  +interface: CallServerEndpointResultInfoInterface,
 };
 export type SendMessagePayload = {
   +localID: string,
   +serverID: string,
   +threadID: string,
   +time: number,
-  +interface: FetchResultInfoInterface,
+  +interface: CallServerEndpointResultInfoInterface,
 };
 
 export type SendTextMessageRequest = {
diff --git a/lib/utils/action-utils.js b/lib/utils/action-utils.js
--- a/lib/utils/action-utils.js
+++ b/lib/utils/action-utils.js
@@ -26,9 +26,12 @@
 } from '../types/session-types';
 import type { ConnectionStatus } from '../types/socket-types';
 import type { CurrentUserInfo } from '../types/user-types';
+import callServerEndpoint from './call-server-endpoint';
+import type {
+  CallServerEndpoint,
+  CallServerEndpointOptions,
+} from './call-server-endpoint';
 import { getConfig } from './config';
-import fetchJSON from './fetch-json';
-import type { FetchJSON, FetchJSONOptions } from './fetch-json';
 
 let nextPromiseIndex = 0;
 
@@ -142,7 +145,9 @@
 };
 
 let currentlyWaitingForNewCookie = false;
-let fetchJSONCallsWaitingForNewCookie: ((fetchJSON: ?FetchJSON) => void)[] = [];
+let serverEndpointCallsWaitingForNewCookie: ((
+  callServerEndpoint: ?CallServerEndpoint,
+) => void)[] = [];
 
 export type DispatchRecoveryAttempt = (
   actionTypes: ActionTypes<'LOG_IN_STARTED', 'LOG_IN_SUCCESS', 'LOG_IN_FAILED'>,
@@ -180,11 +185,11 @@
     return null;
   }
   let newSessionChange = null;
-  let fetchJSONCallback = null;
-  const boundFetchJSON = async (
+  let callServerEndpointCallback = null;
+  const boundCallServerEndpoint = async (
     endpoint: Endpoint,
     data: { [key: string]: mixed },
-    options?: ?FetchJSONOptions,
+    options?: ?CallServerEndpointOptions,
   ) => {
     const innerBoundSetNewSession = (
       sessionChange: ClientSessionChange,
@@ -194,7 +199,7 @@
       setNewSession(dispatch, sessionChange, null, error, source);
     };
     try {
-      const result = await fetchJSON(
+      const result = await callServerEndpoint(
         cookie,
         innerBoundSetNewSession,
         () => new Promise(r => r(null)),
@@ -207,13 +212,13 @@
         data,
         options,
       );
-      if (fetchJSONCallback) {
-        fetchJSONCallback(!!newSessionChange);
+      if (callServerEndpointCallback) {
+        callServerEndpointCallback(!!newSessionChange);
       }
       return result;
     } catch (e) {
-      if (fetchJSONCallback) {
-        fetchJSONCallback(!!newSessionChange);
+      if (callServerEndpointCallback) {
+        callServerEndpointCallback(!!newSessionChange);
       }
       throw e;
     }
@@ -229,10 +234,10 @@
   ) => {
     const startingPayload = { ...inputStartingPayload, source };
     dispatch(wrapActionPromise(actionTypes, promise, null, startingPayload));
-    return new Promise(r => (fetchJSONCallback = r));
+    return new Promise(r => (callServerEndpointCallback = r));
   };
   await resolveInvalidatedCookie(
-    boundFetchJSON,
+    boundCallServerEndpoint,
     dispatchRecoveryAttempt,
     source,
   );
@@ -241,9 +246,9 @@
 
 // Third param is optional and gets called with newCookie if we get a new cookie
 // Necessary to propagate cookie in cookieInvalidationRecovery below
-function bindCookieAndUtilsIntoFetchJSON(
+function bindCookieAndUtilsIntoCallServerEndpoint(
   params: BindServerCallsParams,
-): FetchJSON {
+): CallServerEndpoint {
   const {
     dispatch,
     cookie,
@@ -264,12 +269,13 @@
       error,
       undefined,
     );
-  // This function gets called before fetchJSON sends a request, to make sure
-  // that we're not in the middle of trying to recover an invalidated cookie
+  // This function gets called before callServerEndpoint sends a request,
+  // to make sure that we're not in the middle of trying to recover
+  // an invalidated cookie
   const waitIfCookieInvalidated = () => {
     if (!getConfig().resolveInvalidatedCookie) {
       // If there is no resolveInvalidatedCookie function, just let the caller
-      // fetchJSON instance continue
+      // callServerEndpoint instance continue
       return Promise.resolve(null);
     }
     if (!currentlyWaitingForNewCookie) {
@@ -277,7 +283,7 @@
       return Promise.resolve(null);
     }
     // Wait to run until we get our new cookie
-    return new Promise(r => fetchJSONCallsWaitingForNewCookie.push(r));
+    return new Promise(r => serverEndpointCallsWaitingForNewCookie.push(r));
   };
   // This function is a helper for the next function defined below
   const attemptToResolveInvalidation = async (
@@ -292,11 +298,11 @@
     );
 
     currentlyWaitingForNewCookie = false;
-    const currentWaitingCalls = fetchJSONCallsWaitingForNewCookie;
-    fetchJSONCallsWaitingForNewCookie = [];
+    const currentWaitingCalls = serverEndpointCallsWaitingForNewCookie;
+    serverEndpointCallsWaitingForNewCookie = [];
 
-    const newFetchJSON = newSessionChange
-      ? bindCookieAndUtilsIntoFetchJSON({
+    const newCallServerEndpoint = newSessionChange
+      ? bindCookieAndUtilsIntoCallServerEndpoint({
           ...params,
           cookie: newSessionChange.cookie,
           sessionID: newSessionChange.sessionID,
@@ -304,17 +310,17 @@
         })
       : null;
     for (const func of currentWaitingCalls) {
-      func(newFetchJSON);
+      func(newCallServerEndpoint);
     }
-    return newFetchJSON;
+    return newCallServerEndpoint;
   };
-  // If this function is called, fetchJSON got a response invalidating its
-  // cookie, and is wondering if it should just like... give up? Or if there's
-  // a chance at redemption
+  // If this function is called, callServerEndpoint got a response invalidating
+  // its cookie, and is wondering if it should just like... give up?
+  // Or if there's a chance at redemption
   const cookieInvalidationRecovery = (sessionChange: ClientSessionChange) => {
     if (!getConfig().resolveInvalidatedCookie) {
       // If there is no resolveInvalidatedCookie function, just let the caller
-      // fetchJSON instance continue
+      // callServerEndpoint instance continue
       return Promise.resolve(null);
     }
     if (!loggedIn) {
@@ -323,14 +329,18 @@
       return Promise.resolve(null);
     }
     if (currentlyWaitingForNewCookie) {
-      return new Promise(r => fetchJSONCallsWaitingForNewCookie.push(r));
+      return new Promise(r => serverEndpointCallsWaitingForNewCookie.push(r));
     }
     currentlyWaitingForNewCookie = true;
     return attemptToResolveInvalidation(sessionChange);
   };
 
-  return (endpoint: Endpoint, data: Object, options?: ?FetchJSONOptions) =>
-    fetchJSON(
+  return (
+    endpoint: Endpoint,
+    data: Object,
+    options?: ?CallServerEndpointOptions,
+  ) =>
+    callServerEndpoint(
       cookie,
       boundSetNewSession,
       waitIfCookieInvalidated,
@@ -345,7 +355,7 @@
     );
 }
 
-export type ActionFunc<F> = (fetchJSON: FetchJSON) => F;
+export type ActionFunc<F> = (callServerEndpoint: CallServerEndpoint) => F;
 type BindServerCallsParams = {
   dispatch: Dispatch,
   cookie: ?string,
@@ -357,12 +367,13 @@
 
 // All server calls needs to include some information from the Redux state
 // (namely, the cookie). This information is used deep in the server call,
-// at the point where fetchJSON is called. We don't want to bother propagating
-// the cookie (and any future config info that fetchJSON needs) through to the
-// server calls so they can pass it to fetchJSON. Instead, we "curry" the cookie
-// onto fetchJSON within react-redux's connect's mapStateToProps function, and
-// then pass that "bound" fetchJSON that no longer needs the cookie as a
-// parameter on to the server call.
+// at the point where callServerEndpoint is called. We don't want to bother
+// propagating the cookie (and any future config info that callServerEndpoint
+// needs) through to the server calls so they can pass it to callServerEndpoint.
+// Instead, we "curry" the cookie onto callServerEndpoint within react-redux's
+// connect's mapStateToProps function, and then pass that "bound"
+// callServerEndpoint that no longer needs the cookie as a parameter on to
+// the server call.
 const baseCreateBoundServerCallsSelector = <F>(
   actionFunc: ActionFunc<F>,
 ): (BindServerCallsParams => F) =>
@@ -381,7 +392,7 @@
       currentUserInfo: ?CurrentUserInfo,
       connectionStatus: ConnectionStatus,
     ) => {
-      const boundFetchJSON = bindCookieAndUtilsIntoFetchJSON({
+      const boundCallServerEndpoint = bindCookieAndUtilsIntoCallServerEndpoint({
         dispatch,
         cookie,
         urlPrefix,
@@ -389,7 +400,7 @@
         currentUserInfo,
         connectionStatus,
       });
-      return actionFunc(boundFetchJSON);
+      return actionFunc(boundCallServerEndpoint);
     },
   );
 
diff --git a/lib/utils/fetch-json.js b/lib/utils/call-server-endpoint.js
rename from lib/utils/fetch-json.js
rename to lib/utils/call-server-endpoint.js
--- a/lib/utils/fetch-json.js
+++ b/lib/utils/call-server-endpoint.js
@@ -1,6 +1,6 @@
 // @flow
 
-import { fetchJSONTimeout } from '../shared/timeouts';
+import { callServerEndpointTimeout } from '../shared/timeouts';
 import { SocketOffline, SocketTimeout } from '../socket/inflight-requests';
 import type { Shape } from '../types/core';
 import {
@@ -20,12 +20,12 @@
 import sleep from './sleep';
 import { uploadBlob, type UploadBlob } from './upload-blob';
 
-export type FetchJSONOptions = Shape<{
+export type CallServerEndpointOptions = Shape<{
   // null timeout means no timeout, which is the default for uploadBlob
   +timeout: ?number, // in milliseconds
-  // getResultInfo will be called right before fetchJSON successfully resolves
-  // and includes additional information about the request
-  +getResultInfo: (resultInfo: FetchResultInfo) => mixed,
+  // getResultInfo will be called right before callServerEndpoint successfully
+  // resolves and includes additional information about the request
+  +getResultInfo: (resultInfo: CallServerEndpointResultInfo) => mixed,
   +blobUpload: boolean | UploadBlob,
   // the rest (onProgress, abortHandler) only work with blobUpload
   +onProgress: (percent: number) => void,
@@ -33,26 +33,27 @@
   +abortHandler: (abort: () => void) => void,
 }>;
 
-export type FetchResultInfoInterface = 'socket' | 'REST';
-export type FetchResultInfo = {
-  +interface: FetchResultInfoInterface,
+export type CallServerEndpointResultInfoInterface = 'socket' | 'REST';
+export type CallServerEndpointResultInfo = {
+  +interface: CallServerEndpointResultInfoInterface,
 };
 
-export type FetchJSONServerResponse = Shape<{
+export type CallServerEndpointResponse = Shape<{
   +cookieChange: ServerSessionChange,
   +currentUserInfo: CurrentUserInfo,
   +error: string,
   +payload: Object,
 }>;
 
-// You'll notice that this is not the type of the fetchJSON function below. This
-// is because the first several parameters to that functon get bound in by the
-// helpers in lib/utils/action-utils.js. This type represents the form of the
-// fetchJSON function that gets passed to the action function in lib/actions.
-export type FetchJSON = (
+// You'll notice that this is not the type of the callServerEndpoint
+// function below. This is because the first several parameters to that
+// function get bound in by the helpers in lib/utils/action-utils.js.
+// This type represents the form of the callServerEndpoint function that
+// gets passed to the action function in lib/actions.
+export type CallServerEndpoint = (
   endpoint: Endpoint,
   input: Object,
-  options?: ?FetchJSONOptions,
+  options?: ?CallServerEndpointOptions,
 ) => Promise<Object>;
 
 type RequestData = {
@@ -68,20 +69,20 @@
 // underlying implementations and prefer for things to be explicit, and XSS
 // isn't a thing on native. Note that for native, cookie might be null
 // (indicating we don't have one), and we will then set an empty Cookie header.
-async function fetchJSON(
+async function callServerEndpoint(
   cookie: ?string,
   setNewSession: (sessionChange: ClientSessionChange, error: ?string) => void,
-  waitIfCookieInvalidated: () => Promise<?FetchJSON>,
+  waitIfCookieInvalidated: () => Promise<?CallServerEndpoint>,
   cookieInvalidationRecovery: (
     sessionChange: ClientSessionChange,
-  ) => Promise<?FetchJSON>,
+  ) => Promise<?CallServerEndpoint>,
   urlPrefix: string,
   sessionID: ?string,
   connectionStatus: ConnectionStatus,
   socketAPIHandler: ?SocketAPIHandler,
   endpoint: Endpoint,
   input: { [key: string]: mixed },
-  options?: ?FetchJSONOptions,
+  options?: ?CallServerEndpointOptions,
 ): Promise<Object> {
   const possibleReplacement = await waitIfCookieInvalidated();
   if (possibleReplacement) {
@@ -140,7 +141,7 @@
       // is not logged in on web.
       mergedData.sessionID = sessionID ? sessionID : null;
     }
-    const fetchPromise = (async (): Promise<FetchJSONServerResponse> => {
+    const callEndpointPromise = (async (): Promise<CallServerEndpointResponse> => {
       const response = await fetch(url, {
         method: 'POST',
         // This is necessary to allow cookie headers to get passed down to us
@@ -161,18 +162,18 @@
     })();
 
     const timeout =
-      options && options.timeout ? options.timeout : fetchJSONTimeout;
+      options && options.timeout ? options.timeout : callServerEndpointTimeout;
     if (!timeout) {
-      json = await fetchPromise;
+      json = await callEndpointPromise;
     } else {
       const rejectPromise = (async () => {
         await sleep(timeout);
         throw new FetchTimeout(
-          `fetchJSON timed out call to ${endpoint}`,
+          `callServerEndpoint timed out call to ${endpoint}`,
           endpoint,
         );
       })();
-      json = await Promise.race([fetchPromise, rejectPromise]);
+      json = await Promise.race([callEndpointPromise, rejectPromise]);
     }
   }
 
@@ -201,4 +202,4 @@
   return json;
 }
 
-export default fetchJSON;
+export default callServerEndpoint;
diff --git a/lib/utils/config.js b/lib/utils/config.js
--- a/lib/utils/config.js
+++ b/lib/utils/config.js
@@ -5,11 +5,11 @@
 import type { LogInActionSource } from '../types/account-types';
 import type { PlatformDetails } from '../types/device-types';
 import type { DispatchRecoveryAttempt } from './action-utils';
-import type { FetchJSON } from './fetch-json';
+import type { CallServerEndpoint } from './call-server-endpoint';
 
 export type Config = {
   +resolveInvalidatedCookie: ?(
-    fetchJSON: FetchJSON,
+    callServerEndpoint: CallServerEndpoint,
     dispatchRecoveryAttempt: DispatchRecoveryAttempt,
     source?: LogInActionSource,
   ) => Promise<void>,
diff --git a/lib/utils/upload-blob.js b/lib/utils/upload-blob.js
--- a/lib/utils/upload-blob.js
+++ b/lib/utils/upload-blob.js
@@ -3,16 +3,19 @@
 import invariant from 'invariant';
 import _throttle from 'lodash/throttle';
 
+import type {
+  CallServerEndpointOptions,
+  CallServerEndpointResponse,
+} from './call-server-endpoint';
 import { getConfig } from './config';
-import type { FetchJSONOptions, FetchJSONServerResponse } from './fetch-json';
 
 function uploadBlob(
   url: string,
   cookie: ?string,
   sessionID: ?string,
   input: { [key: string]: mixed },
-  options?: ?FetchJSONOptions,
-): Promise<FetchJSONServerResponse> {
+  options?: ?CallServerEndpointOptions,
+): Promise<CallServerEndpointResponse> {
   const formData = new FormData();
   if (getConfig().setCookieOnRequest) {
     // We make sure that if setCookieOnRequest is true, we never set cookie to
diff --git a/native/account/resolve-invalidated-cookie.js b/native/account/resolve-invalidated-cookie.js
--- a/native/account/resolve-invalidated-cookie.js
+++ b/native/account/resolve-invalidated-cookie.js
@@ -3,7 +3,7 @@
 import { logInActionTypes, logIn } from 'lib/actions/user-actions';
 import type { LogInActionSource } from 'lib/types/account-types';
 import type { DispatchRecoveryAttempt } from 'lib/utils/action-utils';
-import type { FetchJSON } from 'lib/utils/fetch-json';
+import type { CallServerEndpoint } from 'lib/utils/call-server-endpoint';
 
 import { getGlobalNavContext } from '../navigation/icky-global';
 import { store } from '../redux/redux-setup';
@@ -11,7 +11,7 @@
 import { fetchNativeKeychainCredentials } from './native-credentials';
 
 async function resolveInvalidatedCookie(
-  fetchJSON: FetchJSON,
+  callServerEndpoint: CallServerEndpoint,
   dispatchRecoveryAttempt: DispatchRecoveryAttempt,
   source?: LogInActionSource,
 ) {
@@ -26,7 +26,7 @@
   const { calendarQuery } = extraInfo;
   await dispatchRecoveryAttempt(
     logInActionTypes,
-    logIn(fetchJSON)({
+    logIn(callServerEndpoint)({
       ...keychainCredentials,
       ...extraInfo,
       source,
diff --git a/native/input/input-state-container.react.js b/native/input/input-state-container.react.js
--- a/native/input/input-state-container.react.js
+++ b/native/input/input-state-container.react.js
@@ -75,12 +75,12 @@
   useServerCall,
   useDispatchActionPromise,
 } from 'lib/utils/action-utils';
+import type {
+  CallServerEndpointOptions,
+  CallServerEndpointResponse,
+} from 'lib/utils/call-server-endpoint';
 import { getConfig } from 'lib/utils/config';
 import { getMessageForException, cloneError } from 'lib/utils/errors';
-import type {
-  FetchJSONOptions,
-  FetchJSONServerResponse,
-} from 'lib/utils/fetch-json';
 import { values } from 'lib/utils/objects';
 import { useIsReportEnabled } from 'lib/utils/report-utils';
 
@@ -897,8 +897,8 @@
     cookie: ?string,
     sessionID: ?string,
     input: { [key: string]: mixed },
-    options?: ?FetchJSONOptions,
-  ): Promise<FetchJSONServerResponse> => {
+    options?: ?CallServerEndpointOptions,
+  ): Promise<CallServerEndpointResponse> => {
     invariant(
       cookie &&
         input.multimedia &&