ukrrus

API для доступа к данным

Введение

На этой странице публикуется описание работы серверного API. Обо всех ошибочных ситуациях или неточностях в описании сообщать на info@home.finance.ua или писать на форуме. Периодически документация пополняется описаниями новых методов.

Для осуществления доступа к данным аккаунта Домашних Финансов используются POST-запросы типа «application/json» с json-содержанием. Для авторазиции возможно использование https. Для работы с данными аккаунта по https разрешена работа только для аккаунтов с ненулевым балансом.

Все запросы должны направляться на адрес [PROTOCOL]://home.finance.ua/services/index.php В ответе сервера клиенту содержится строка с JSON-данными. Виды запросов-ответов и формат передаваемых данных рассмотрены ниже.

Внимание! Согласно пункту 1.3 Cоглашения об использовании службы «API Домашние Финансы», оно вступает в силу с момента первого использования Разработчиком любой функции API Домашних Финансов.

Общая структура запросов и ответов

Все запросы к серверу в качестве данных должны передавать JSON-объект следующего вида:


{
    "id":ID_REQUEST,
    "service":SERVICE_NAME,
    "method":METHOD_NAME,
    "params":[]
}


Поле params используется для передачи параметров. Остальные поля носят служебный характер и являются либо идентификатором (ID_REQUEST), либо имеют одно из служебных предопределенных значений

Содержание успешного ответа сервера будет таким:


{
    "result":DATA,
    "id":ID_REQUEST
}


Содержание ответа с ошибкой - таким:


{
    "error":
    {
        "message":SOME_TEXT,
        "code":ERROR_ID,
        "origin":2
    },
    "id":ID_REQUEST
}

ID_REQUEST — уникальный идентификатор запроса, который должен быть задан клиентом в теле запроса и будет возвращен в теле ответа на данный запрос.
ERROR_ID - один из служебных идентификаторов ошибки, может принимать следующие значения:
  • 50 — сессия невалидна
  • 51 — у данного пользователя нет прав для совершения в данном бюджетном аккаунте запрашиваемого действия
  • 52 — попытка работать по https протоколу в бесплатном аккаунте
  • 53 — исчерпано количество сессионных дней для данного бесплатного аккаунта
  • 54 — попытка работать в аккаунте (не своем) у которого нулевой баланс
  • 55 — попытка сменить тип бюджетной сетки на бесплатном аккаунте
  • 56 — попытка смотреть историю бюджетного аккаунта, недоступную для бесплатного аккаунта
  • 57 — неверный E-mail или пароль при авторизации

Авторизация в системе

Для авторизации в системе клиент должен отправить на сервер запрос с такой структурой поля params:


{
    "email":E-MAI,
    "password":PASSWORD
}


При успешной авторизации поле result ответа будет следующим:


{
    "token":TOKEN,
    "idUser":ID_USER,
    "idAccount":ID_ACCOUNT,
    "role":ID_ROLE
}
  • E-MAIL — регистрационный E-mail пользователя
  • PASSWORD — пароль пользователя
  • TOKEN — ключ, который будет использоваться для идентификации сессии работы с бэк-ендом. После успешной авторизации в системе TOKEN не изменяется на протяжении всего сеанса работы с системой. Если на протяжении 3 суток в данном сеансе работы небыло активности — TOKEN становится невалидным.
  • ID_USER — идентификатор пользователя
  • ID_ACCOUNT — идентификатор бюджетного аккаунта. После авторизации возвращается номер дефолтового бюджетного аккаунта пользователя
  • ID_ROLE — права доступа пользователя ID_USER к аккаунту ID_ACCOUNT
Пример запроса на авторизацию:


{
    "id":1,
    "service":"sauth",
    "method":"auth",
    "params":[
        {
            "email":"info@home.finance.ua",
            "password":"123123"
        }
    ]
}


Пример ответа на запрос:


{
    "result":
    {
        "token":"b6b7de813811acfa24d198adc4de0c6e",
        "idUser":"35",
        "idAccount":"35",
        "role":"5"
    },
    "id":1
}


После успешной авторизации данные ID_TOKEN, ID_USER и ID_ACCOUNT должны присутствовать в параметрах каждого запроса к серверу. На основании этих данных проверяется валидность текущего сеанса работы с бек-эндом, права пользователя ID_USER на произведение запрашиваемых действий в аккаунте ID_ACCOUNT и т. д. Поле “params” запросов в рабочем режиме является массивом из двух элементов, где в первом передаются сессионные данные, а во втором — пользовательские данные. Общая структура запросов в этом случае принимает вид:


{
    /*Уникальный номер запроса*/
    "id" : ID_REQUEST,

    /*Название сервиса*/
    "service" : SERVICE_NAME,

    /*Название метода сервиса*/
    "method" : METHOD_NAME,

    "params" :
    [
        /*0-й элемент массива — служебные данные, которые должны быть всегда*/
        {
            "token" : TOKEN,
            "idAccount" : ID_ACCOUNT,
            "idUser" : ID_USER
        },

        /*Для каждого типа запросов структура этих данных своя*/
        REQUEST_DATA
    ]
}

Получение настроек бюджетного аккаунта

Для получения настроек бюджетного аккаунта поля запроса должны принимать следующие значения:
  • SERVICE_NAME = ssettings
  • METHOD_NAME = read
  • REQUEST_DATA — массив, в котором в виде строк перечислены типы запрашиваемых настроек аккаунта.
Возможные типы запрашиваемых настроек (для массива REQUEST_DATA):
  • "ctgs" - категории расходов и доходов
  • "scheta" - счета
  • "currencies" - валюты
  • "budgetGrid" - настройки бюджетной сетки
  • "userSettings" - настройки пользователя
  • "finTargets" - финансовые цели
  • "summaryBlocks" - виджеты "Итогов"
  • "commonSettings" - разное
  • "userAccounts" - бюджетные аккаунты пользователя
  • "accountUsers" - пользователи бюджетного аккаунта
  • "accountDate" - серверное "сегодня"
Общая структура ответа на запрос описана выше. Структура поля result для данного запроса в общем выглядит так:


{
    "SETTINGS_1_NAME" : DATA_1,
    "SETTINGS_2_NAME" : DATA_2,
...
}

Здесь [SETTINGS_I_NAME] - это название типа запрашиваемой настройки, DATA_I - данные, которые для каждого типа настроек имеют свою структуру.

Для "ctgs" поле DATA_I будет следующим:


{
    "ctgsCosts" : [
        {
            /*Название категории*/
            "title":CTG_1 TITLE,

            /*Плановое значение категории*/
            "pred":CTG_1_PLAN,

            /*Временная метка даты, с которой категория считается отключенной.
            0 - если категория включена*/

            "disabledFrom":CTG_1_DISABLED_FROM
        },
        {
            "title":CTG_2 TITLE,
            "pred":CTG_2_PLAN,
            "disabledFrom":CTG_2_DISABLED_FROM
        },
        ...
    ],
    "ctgsRevenues" : [
        {
            /*Название категории*/
            "title":CTG_1 TITLE,

            /*Плановое значение категории*/
            "pred":CTG_1_PLAN

            /*Временная метка даты, с которой категория считается отключенной.
            0 - если категория включена*/

            "disabledFrom":CTG_1_DISABLED_FROM
        },
        {
            "title":CTG_2 TITLE,
            "pred":CTG_2_PLAN,
            "disabledFrom":CTG_2_DISABLED_FROM
        },
        ...
    ]
}


Для "scheta" поле DATA_I будет следующим:


[
    {
        /*Название счета*/
        "title":SCHET_1_TITLE,

        /*Временная метка даты, с которой счет считается отключенным.
        0 - если счет включен*/

        "disabledFrom":SCHET_1_DISABLED_FROM
    },
    {
        "title":SCHET_2_TITLE,
        "disabledFrom":SCHET_2_DISABLED_FROM
    },
    ...
]


Для "currencies" поле DATA_I будет следующим:


{
    /*числовой ID валюты*/
    CURRENCY_1_ID:
    {
        /*Название валюты*/
        "title":CURRENCY_1_TITLE,

        /*Флаг активированности валюты для аккаунта, 1 - активирована, 0 - отключена*/
        "active":CURRENCY_1_ACTIVE_FLAG,
    },
    CURRENCY_2_ID:
    {
        "title":CURRENCY_2_TITLE,
        "active":CURRENCY_2_ACTIVE_FLAG,
    },
    ...
}


Для "budgetGrid" поле DATA_I будет следующим:


{
    /*Тип бюджетной сетки, 1 - недельная, 2 - месячная, 3 - квартальная*/
    "periodType":PERIOD_TYPE_VALUE,

    /*Номер дня начала бюджетного периода для месячной сетки*/
    "pstart":PSTART_VALUE,

    /*Дата первой операции аккаунта*/
    "minDate":MINDATE_VALUE
}


Для "userSettings" поле DATA_I будет следующим:


{
    /*E-mail авторизованного пользователя*/
    "email":EMAIL_VALUE,

    /*Согласие пользователя получать новости системы на свой
    почтовый ящик, 0 - нет, 1 - да*/

    "receiveNews":RECEIVE_NEWS_VALUE,

    /*Язык интерфейса приложения, 0 - русский, 1 - украинский*/
    "lang":LANG_VALUE,

    /*Ник пользователя*/
    "username":USERNAME_VALUE,

    /*Идентификатор основного бюджетного аккаунта пользователя,
    который активируется при авторизации*/

    "mainAccount":MAIN_ACCOUNT_VALUE,

    /*Количество дней без активности в аккаунте, после которого пользователь
    получит напоминание на e-mail*/

    "noActivityRemind":NO_ACTIVITY_REMIND_VALUE,

}


Для "finTargets" поле DATA_I будет следующим:


[
    {
        /*Название финансовой цели №1*/
        "title":FIN_TARGET_1_TITLE},

        /*Номер счета, используемый для финансовой цели №1*/
        "idSchet":FIN_TARGET_1_ID_SCHET},

        /*Номер валюты, остаток в которой идет в зачет финансовой цели №1*/
        "idCurrency":FIN_TARGET_1_ID_CURRENCY},

        /*Начальное значение остатков при старте выполнения финансовой цели №1*/
        "startValue":FIN_TARGET_1_START_VALUE},

        /*Конечное значение остатков, при котором финансовая цель №1 будет выполнена*/
        "finishValue":FIN_TARGET_1_FINISH_VALUE},

        /*Дата начала выполнения финансовой цели №1*/
        "startDate":FIN_TARGET_1_START_DATE},

        /*Дата окончания выполнения финансовой цели №1*/
        "finishDate":FIN_TARGET_1_FINISH_DATE},

        /*Текстовое описание финансовой цели №1*/
        "description":FIN_TARGET_1_DESCRIPTION
    }
    ...
]


Для "summaryBlocks" поле DATA_I будет следующим:


[
    {
        /*Название виджета №1*/
        "title":BLOCK_1_TITLE},

        /*Тип виджета №1, 0 - расходы, 1 - доходы, 2 - остатки на счетах*/
        "type":BLOCK_1_TYPE},

        /*Настройки блока №1, массив идентификаторов, соответствено,
        категорий расходов, категорий доходов, счетов*/

        "data":BLOCK_1_ARRAY},
    }
    ...
]


Для "commonSettings" поле DATA_I будет следующим:


{
    /*Номер основной валюты бюджетного аккаунта*/
    "mainCurrency":MAIN_CURRENCY_VALUE},

    /*Название бюджетного аккаунта*/
    "accountTitle":ACCOUNT_TITLE_VALUE},

    /*Массив из 3-х номеров телефонов (последние 7-м цифр номеров),
    используемых в SMS-сервисе*/

    "smsNumbers":SMS_NUMBERS_ARRAY}
}


Для "userAccounts" поле DATA_I будет следующим:


[
    {
        /*Номер бюджетного аккаунта №1 пользователя */
        "id":ACCOUNT_1_ID_VALUE},

        /*Название бюджетного аккаунта №1 пользователя */
        "title":ACCOUNT_1_TITLE_VALUE},

        /*Права пользователя в бюджетном аккаунте №1, 0 - нет доступа,
        1 - Администратор, 2 - Опытный редактор, 3 - Редактор,
        4 - Пользователь, 5 - Гость*/

        "role":ACCOUNT_1_ROLE_VALUE},

        /*Флаг подтверждения участия пользователя в бюджетном аккаунте, 0 - нет, 1 - да*/
        "accepted":ACCOUNT_1_ACCEPTED_VALUE}
    }
    ...
]


Для "accountUsers" поле DATA_I будет следующим:


[
    {
        /*Номер пользователя №1 бюджетного аккаунта*/
        "id":USER_1_ID_VALUE},

        /*Имя пользователя №1 бюджетного аккаунта*/
        "username":USER_1_USERNAME_VALUE},

        /*Права пользователя №1 в бюджетном аккаунте , 0 - нет доступа,
        1 - Администратор, 2 - Опытный редактор, 3 - Редактор,
        4 - Пользователь, 5 - Гость*/

        "role":USER_1_ROLE_VALUE},

        /*E-mail пользователя №1 бюджетного аккаунта*/
        "email":USER_1_EMAIL_VALUE}
    }
    ...
]


Для "accountDate" поле DATA_I будет следующим:


/*Метка 00:00:00 по GMT текущих суток сервера*/
ACCOUNT_DATE_MARK


Пример запроса на получение только списка категорий и счетов:


{
    "service":"ssettings",
    "method":"read",
    "id":3,
    "params":[

        /*0-й элемент массива params - идентификаторы*/
        {
            "token":"4f35fc9c0743e506108b13944b1d1291",
            "idUser":"1",
            "idAccount":"1"
        },

        /*1-й элемент массива params - данные (перечисление типов запрашиваемых настроек)*/
        ["ctgs","scheta"]
    ]
}


Пример ответа на запрос получения списка категорий и счетов:


{
    "result":{
        "ctgs":{
            "ctgsCosts":[
                {"title":"Продукты","pred":"0.00","disabledFrom":"0"},
                {"title":"Проезд","pred":"0.00","disabledFrom":"1327449600"},
                {"title":"Развлечения","pred":"0.00","disabledFrom":"0"}
            ],
            "ctgsRevenues":[
                {"title":"Зарплата","pred":"0.00","disabledFrom":"0"},
                {"title":"Подработка","pred":"0.00","disabledFrom":"0"},
            ]
        },
        "scheta":[
            {"title":"Кошелек","disabledFrom":"0"},
            {"title":"Конверт","disabledFrom":"1327449600"}
        ]
    },
    "id":3
}

Запись настроек бюджетного аккаунта

Для записи настроек бюджетного аккаунта поля запроса должны принимать следующие значения:
  • SERVICE_NAME = ssettings
  • METHOD_NAME = write
  • REQUEST_DATA — структура параметра описана ниже

{
    "SETTINGS_1_NAME" : DATA_1,
    "SETTINGS_2_NAME" : DATA_2,
...
}
Как и при чтении настроек, разные типы настроек можно (и нужно) группировать и отправлять в одном запросе.

Для сохранения изменений в списке категорий расходов, на сервер необходимо отправить полный список категорий расходов, который заменит хранящийся в текущий момент на сервере. Порядок категорий в структуре должен совпадать с порядком категорий при отображении. То же самое касается сохранения категорий доходов и счетов.

Пример запроса на замещение списков категорий расходов, доходов и счетов:


{
    "ctgs":{
        "ctgsCosts":[
            {"title":"Продукты бла-бла","pred":"0.00","disabledFrom":"0"},
            {"title":"Проезд бла-бла","pred":"0.00","disabledFrom":"0"},
            {"title":"Развлечения бла-бла","pred":"0.00","disabledFrom":"0"}
        ],
        "ctgsRevenues":[
            {"title":"Зарплата бла-бла","pred":"0.00","disabledFrom":"0"}
        ]
    },
    "scheta":[
        {"title":"Кошелек бла-бла","disabledFrom":"0"},
        {"title":"Конверт бла-бла","disabledFrom":"1327449600"},
        {"title":"Карточка","disabledFrom":"1327449600"}
    ]
}
Если такой запрос на сохранение будет отправлен для данных, полученных в примере чтения настроек, то:
  • Все три категории расходов будут переименованы
  • Первая категория доходов будет переименована, а вторая удалена
  • Два счета аккаунта будут переименованы, и к ним будет добавлен еще один


Для сохранения настроек бюджетной сетки (budgetGrid) поле DATA_I должно быть следующим:


{
    /*Тип бюджетной сетки, 1 - недельная, 2 - месячная, 3 - квартальная*/
    "periodType":PERIOD_TYPE_VALUE,

    /*Номер дня начала бюджетного периода для месячной сетки*/
    "pstart":PSTART_VALUE,
}


Для сохранения настроек бюджетной сетки (budgetGrid) поле DATA_I должно быть следующим:


{
    /*Тип бюджетной сетки, 1 - недельная, 2 - месячная, 3 - квартальная*/
    "periodType":PERIOD_TYPE_VALUE,

    /*Номер дня начала бюджетного периода для месячной сетки*/
    "pstart":PSTART_VALUE,
}


Для сохранения настроек пользователя ("userSettings") поле DATA_I должно быть следующим:


{
    /*E-mail авторизованного пользователя*/
    "email":EMAIL_VALUE,

    /*Согласие пользователя получать новости системы на свой
    почтовый ящик, 0 - нет, 1 - да*/

    "receiveNews":RECEIVE_NEWS_VALUE,

    /*Язык интерфейса приложения, 0 - русский, 1 - украинский*/
    "lang":LANG_VALUE,

    /*Ник пользователя*/
    "username":USERNAME_VALUE,

    /*Идентификатор основного бюджетного аккаунта пользователя,
    который активируется при авторизации*/

    "mainAccount":MAIN_ACCOUNT_VALUE,

    /*Количество дней без активности в аккаунте, после которого пользователь 
    получит напоминание на e-mail*/

    "noActivityRemind":NO_ACTIVITY_REMIND_VALUE,

    /*Значение нового пароля пользователя. Пустая строка в параметре - пароль
    не будет изменен*/

    "newPassword":NEW_PASSWORD_VALUE,
}


Для сохранения финансовых целей ("finTargets") поле DATA_I должно быть таким же, как и при чтении - массив объектов с данными каждой финансовой цели.

Для сохранения настроек виджетов ("summaryBlocks") поле DATA_I должно быть таким же, как и при чтении - массив объектов с данными по каждому виджету.

Для сохранения общих настроек ("сommonSettings") поле DATA_I должно быть таким же, как и при чтении.

Для сохранения списка аккаунтов пользователя ("userAccounts") поле DATA_I должно быть таким же, как и при чтении - массив объектов с данными по каждому аккаунту пользователя.

Для сохранения списка пользователей аккаунта ("аccountUsers") поле DATA_I должно быть таким же, как и при чтении - массив объектов с данными по каждому пользователю аккаунта.

Чтение операций

Для получения операций (расходов, доходов и переводов) бюджетного аккаунта поля запроса должны принимать следующие значения:
  • SERVICE_NAME = soperations
  • METHOD_NAME = read
  • REQUEST_DATA — {"fromdate":FROM_DATE_VALUE, "todate":TO_DATE_VALUE, "today":TODAY_VALUE}
FROM_DATE_VALUE и TO_DATE_VALUE определяют временной отрезок запрашиваемых операций. В ответе будут содержаться операции всех типов (расходы, доходы, переводы) и всех видов (совершонные, будущие, просроченные), дата которых находится в отрезка указанных дат.

TODAY_VALUE - "сегодняшняя" дата клиента - дата актуальности учета.

Даты должны быть указаны в формате временных меток (количество секунд с 00:00:00 01-01-1970 до 00:00:00 соответствующих суток по GMT)

Поле result ответа будет иметь следующий формат:

{
    /*Расходы*/
    "costs":{
        /*Массив идентификаторов операций*/
        "id":[],

        /*Массив дат операций*/
        "date":[],

        /*Массив комментариев операций*/
        "comment":[],

        /*Массив типов операций (1 - совершенная, 2 - будущая)*/
        "realtype":[],

        /*Массив сумм операций*/
        "sum":[],

        /*Массив идентификаторов валют операций*/
        "idCurrency":[],

        /*Массив идентификаторов категорий операций*/
        "idCtg":[],

        /*Массив идентификаторов счетов операций*/
        "idSchet":[],

        /*Массив идентификаторов авторов или последник редакторов операций*/
        "idUser":[]
    },

    /*Доходы*/
    "revenues":{
        "id":[],
        "date":[],
        "comment":[],
        "realtype":[],
        "sum":[],
        "idCurrency":[],
        "idCtg":[],
        "idSchet":[],
        "idUser":[]
    },

    /*Переводы*/
    "transfers":{
        "id":[],
        "date":[],
        "comment":[],
        "realtype":[],

        /*Исходные суммы переводов*/
        "sumFrom":[],

        /*Исходные валюты переводов*/
        "idCurrencyFrom":[],

        /*Исходные счета переводов*/
        "idSchetFrom":[],

        /*Конечные суммы переводов*/
        "sumTo":[],

        /*Конечные валюты переводов*/
        "idCurrencyTo":[],

        /*Конечные счета переводов*/
        "idSchetTo":[],

        "idUser":[]
    },
    /*Курсы валют для дней из запрашиваемого временного отрезка.
    Формат поля будет описан позже*/

    "rates":[],

    /*Курсы валют сегодняшнего (для сервера) дня.
    Формат поля будет описан позже*/

    "realtodayRates":[],

    /*Данные, необходимые для расчета начального сальдо запрашиваемого
    временного отрезка. Формат поля будет описан позже*/

    "startSaldo":[]
}



Запись операций

Для записи новых (добавленных) операций, сохранения изменений в уже существующих операциях и удаления существующих операций поля запроса должны принимать следующие значения:
  • SERVICE_NAME = soperations
  • METHOD_NAME = write
  • REQUEST_DATA — структура параметра описана ниже

[
    {
        /*Тип действия, 0 - новая операция, 1 - редактирование операции,
        2 - удаление операции*/

        "operationActionType":OPERATION_ACTION_TYPE_VALUE,

        /*Объект данных операции*/
        "operationObject":OPERATION_OBJECT
    },
    ...
]


В одном запросе могут (и должны) передаваться группы действий над операциями.

Для операции "расхода" OPERATION_OBJECT имеет вид:


{
    "id":OPERATION_ID_VALUE,
    "type":0,
    "date":OPERATION_DATE_VALUE,
    "comment":OPERATION_COMMENT_VALUE,
    "sum":OPERATION_SUM_VALUE,
    "idCurrency":OPERATION_ID_CURRENCY_VALUE,
    "idCtg":OPERATION_ID_CTG_VALUE,
    "idSchet":OPERATION_ID_SCHET_VALUE
}


Для операции "дохода" OPERATION_OBJECT имеет вид:


{
    "id":OPERATION_ID_VALUE,
    "type":1,
    "date":OPERATION_DATE_VALUE,
    "comment":OPERATION_COMMENT_VALUE,
    "sum":OPERATION_SUM_VALUE,
    "idCurrency":OPERATION_ID_CURRENCY_VALUE,
    "idCtg":OPERATION_ID_CTG_VALUE,
    "idSchet":OPERATION_ID_SCHET_VALUE
}


Для операции "перевода" OPERATION_OBJECT имеет вид:


{
    "id":OPERATION_ID_VALUE,
    "type":2,
    "date":OPERATION_DATE_VALUE,
    "comment":OPERATION_COMMENT_VALUE,
    "sumFrom":OPERATION_SOURCE_SUM_VALUE,
    "idCurrencyFrom":OPERATION_ID_SOURCE_CURRENCY_VALUE,
    "idSchetFrom":OPERATION_ID_SOURCE_SCHET_VALUE,
    "sumTo":OPERATION_TARGET_SUM_VALUE,
    "idCurrencyTo":OPERATION_ID_TARGET_CURRENCY_VALUE,
    "idSchetTo":OPERATION_ID_TARGET_SCHET_VALUE
}


Независимо от типа действия над операцией, в OPERATION_OBJECT передается полный набор полей операции.

Для новых операций в поле OPERATION_ID_VALUE должен передаваться уникальный идентификатор операции, не совпадающий с идентификаторами уже существующих операций. Рекомендуется в качестве идентификаторов новых (еще не сохраненных на сервер) операций использовать целые отрицательные значения (-1, -2 и т.д.). В таком виде идентификатор будет существовать до сохранения операции на сервер, а после сохранения он должен быть заменен на "серверный" идентификатор, который приходит в ответе на запрос (см. ниже).

Пример запроса на создание одного расхода, редактирование одного расхода, и удаление одного расхода:


{
    "service":"soperations",
    "method":"write",
    "id":7,
    "params":[
        {
            "token":"0c07c8ebd81d938e751c7304ae9ee908",
            "idUser":"35",
            "idAccount":"35"
        },
        [
            {
                "operationActionType":0,
                "operationObject":
                {
                    "id":-1,
                    "type":0,
                    "date":1308528000,
                    "comment":"ffff",
                    "sum":123,
                    "idCurrency":2,
                    "idCtg":0,
                    "idSchet":0
                }
            },
            {
                "operationActionType":1,
                "operationObject":
                {
                    "id":961274,
                    "type":0,
                    "date":1304121600,
                    "comment":"Магелан автоматы123",
                    "sum":50,
                    "idCurrency":1,
                    "idCtg":6,
                    "idSchet":0
                }
            },
            {
                "operationActionType":2,
                "operationObject":
                {
                    "id":962561,
                    "type":0,
                    "date":1304208000,
                    "comment":
                    "посидели в клубе",
                    "sum":200,
                    "idCurrency":1,
                    "idCtg":11,
                    "idSchet":0
                }
            }
        ]
    ]
}


В ответе сервера обязательно присутствует поле oldNewIds. Если в запросе присутствовали действия по созданию новых операций - в поле (массиве) oldNewIds будет передана информация определяющая соответствие между временными (отрицательными) идентификаторами операций на клиенте и постоянными (инициализированными на сервере) идентификаторами тех же операций.

Пример ответа на запрос о создании одного нового расхода:


{
    "result":
    {
        "oldNewIds":
        [
            {
                /*Тип операции*/
                "type":0,

                /*Клиентский "временный" идентификатор*/
                "oldId":-1,

                /*Серверный "постоянный" идентификатор*/
                "newId":32302
            }
        ]
    ,"comment":""
    },
    "id":1
}


В случае ошибок обработки действий по отдельным операциям (операция не может быть создана из-за превышения лимита, действие над операцией не может быть реализовано из-за ограничения прав пользователя, невозможно удаление операции из-за ее отсутствия и т.п.) - все остальные действия над операциями производятся без ограничений, а в поле comment передается комментарий о возникших проблемах.
Подсчитывай свои возможности,
cравнивай их со своими потребностями,
рассчитывай и корректируй затраты и доходы
вместе с Домашними Финансами