diff --git a/scripts/importData.bat b/scripts/importData.bat
index 7e88f9f12e8fc6799a5429e6c30f413bfb01c012..2f3eb2efe7da13a17809a8b23c7cc38e4640037b 100644
--- a/scripts/importData.bat
+++ b/scripts/importData.bat
@@ -1,4 +1,4 @@
 @echo off
 echo Please provide cozysessid (can be found after connection in browser dev tool)
 set /p token="CozySessid ? : "
-ACH -t %token% import ./data/dayData.json
+ACH -t %token% -u http://cozy.tools:8080 import ./data/dayData.json
diff --git a/src/components/TotalConsumption/TotalConsumption.tsx b/src/components/TotalConsumption/TotalConsumption.tsx
index cd64092a83fc4a76bcdaa9cb5b8796cff29e25d4..5d0991f610c815a23a98e0523039b3e7ef49cb41 100644
--- a/src/components/TotalConsumption/TotalConsumption.tsx
+++ b/src/components/TotalConsumption/TotalConsumption.tsx
@@ -37,9 +37,15 @@ const TotalConsumption: React.FC<TotalConsumptionProps> = ({
 
       const converterService = new ConverterService()
       let total = 0
+      let totalPrice = 0
 
       actualData.forEach(data => {
-        if (data.value !== -1) total += data.value
+        if (data.value !== -1) {
+          total += data.value
+        }
+        if (data.price) {
+          totalPrice += converterService.LoadToEuro(data.price, fluidType)
+        }
       })
 
       const displayedValue =
@@ -50,9 +56,7 @@ const TotalConsumption: React.FC<TotalConsumptionProps> = ({
           ? '-----'
           : fluidType === FluidType.MULTIFLUID
           ? formatNumberValues(total).toString()
-          : formatNumberValues(
-              converterService.LoadToEuro(total, fluidType)
-            ).toString()
+          : formatNumberValues(totalPrice).toString()
 
       setTotalValue(displayedValue)
     }
diff --git a/src/models/dataload.model.ts b/src/models/dataload.model.ts
index 22f7c95ceba53e99bc7c6cc9bd7bc410a83dd2fc..1297ae39ef1adf9328d1ed25923924659b9e9bc8 100644
--- a/src/models/dataload.model.ts
+++ b/src/models/dataload.model.ts
@@ -3,6 +3,7 @@ import { DateTime } from 'luxon'
 export interface Dataload {
   date: DateTime
   value: number
+  price: number
   valueDetail: number[] | null
 }
 
diff --git a/src/models/indicator.model.ts b/src/models/indicator.model.ts
index dbff5acc5560a035a2042f98a44e9ee7142cd7a1..35174f34242e15216a060f404041ded622e78e7a 100644
--- a/src/models/indicator.model.ts
+++ b/src/models/indicator.model.ts
@@ -2,4 +2,5 @@ export interface PerformanceIndicator {
   value: number | null
   compareValue: number | null
   percentageVariation: number | null
+  price?: number | null
 }
diff --git a/src/services/consumption.service.ts b/src/services/consumption.service.ts
index d8f492152983973b450a69074959f5d77847b989..de59c7024e9e110ea65cc239a1b4bd37b0f2d165 100644
--- a/src/services/consumption.service.ts
+++ b/src/services/consumption.service.ts
@@ -183,16 +183,22 @@ export default class ConsumptionDataManager {
           value: null,
           compareValue: null,
           percentageVariation: null,
+          price: null,
         }
 
         const actualDataIsValid = this.PerformanceIndicatorsDataIsValid(
           graphData.actualData
         )
 
-        if (actualDataIsValid)
+        if (actualDataIsValid) {
           performanceIndicator.value = this.calculatePerformanceIndicatorValue(
             graphData.actualData
           )
+          if (graphData.actualData[0].price)
+            performanceIndicator.price = this.calculatePerformanceIndicatorPrice(
+              graphData.actualData
+            )
+        }
 
         if (
           actualDataIsValid &&
@@ -229,6 +235,10 @@ export default class ConsumptionDataManager {
     return data.reduce((a, b) => (b.value !== -1 ? a + b.value : a), 0)
   }
 
+  public calculatePerformanceIndicatorPrice(data: Dataload[]): number {
+    return data.reduce((a, b) => (b.price !== null ? a + b.price : a), 0)
+  }
+
   private calculatePerformanceIndicatorVariationPercentage(
     dataSum: number,
     comparisonDataSum: number
@@ -435,7 +445,8 @@ export default class ConsumptionDataManager {
           else {
             convertedValue = converterService.LoadToEuro(
               value,
-              singleFluidChart.chartFluid
+              singleFluidChart.chartFluid,
+              singleFluidChart.chartData.actualData[i].price
             )
             agreggatedConvertedValue += convertedValue
           }
@@ -454,7 +465,8 @@ export default class ConsumptionDataManager {
             else {
               convertedComparisonValue = converterService.LoadToEuro(
                 comparisonValue,
-                singleFluidChart.chartFluid
+                singleFluidChart.chartFluid,
+                singleFluidChart.chartData.comparisonData[i].price
               )
               comparisonAgreggatedConvertedValue += convertedComparisonValue
             }
@@ -525,17 +537,26 @@ export default class ConsumptionDataManager {
     return data.data
   }
 
-  //TODO: replace when merge
   /**
    * Get the first entry of a given data doctype (enedis, grdf, egl)
    * @param doctype
    * @returns
    */
-  public async getFirsDataDateFromDoctype(
+  public async getFirstDataDateFromDoctypeWithPrice(
     doctype: Doctype
   ): Promise<DataloadEntity[] | null> {
     const query: QueryDefinition = Q(doctype)
-      .where({})
+      .where({
+        price: {
+          $exists: false,
+        },
+      })
+      .partialIndex({
+        price: {
+          $exists: false,
+        },
+      })
+      .indexFields(['year', 'month'])
       .sortBy([{ year: 'asc' }, { month: 'asc' }])
       .limitBy(1)
     const data = await this._client.query(query)
@@ -561,15 +582,11 @@ export default class ConsumptionDataManager {
    * @param {DataloadEntity[]} consumptionDocs - Array of doc to save
    * @returns {DataloadEntity[]} Array of saved docs
    */
-  public async saveDocs(
-    consumptionDocs: DataloadEntity[]
-  ): Promise<DataloadEntity[]> {
-    const savedDocs = consumptionDocs.map(async docToUpdate => {
-      const {
-        data: savedDoc,
-      }: QueryResult<DataloadEntity> = await this._client.save(docToUpdate)
-      return savedDoc
-    })
-    return Promise.all(savedDocs)
+  public async saveDocs(consumptionDocs: DataloadEntity[]): Promise<boolean> {
+    const {
+      data: savedDocs,
+    }: QueryResult<DataloadEntity> = await this._client.saveAll(consumptionDocs)
+
+    return true
   }
 }
diff --git a/src/services/converter.service.ts b/src/services/converter.service.ts
index 29519cbbaab475f96b5541b47d1404146f5057ee..92c1bdca2c3c1ccf3b4c468dd98a263742dddac5 100644
--- a/src/services/converter.service.ts
+++ b/src/services/converter.service.ts
@@ -9,13 +9,18 @@ export default class ConverterService {
     this._fluidConfig = new ConfigService().getFluidConfig()
   }
 
-  public LoadToEuro(load: number, fluidType: FluidType): number {
+  public LoadToEuro(
+    load: number,
+    fluidType: FluidType,
+    price?: number | null
+  ): number {
     let convertedLoad: number
     // If Multifluid do not apply coeff because it doesn't exist
     if (fluidType === FluidType.MULTIFLUID) {
       convertedLoad = load
     } else {
-      convertedLoad = load * this._fluidConfig[fluidType].coefficient
+      // convertedLoad = load * this._fluidConfig[fluidType].coefficient
+      convertedLoad = this.applyPrice(this._fluidConfig[fluidType], load, price)
     }
 
     // Prevent round 0 case when the actual value is not 0
@@ -24,4 +29,23 @@ export default class ConverterService {
     }
     return convertedLoad
   }
+
+  /**
+   * Return calculated price
+   * @param {FluidConfig} fluidConfig - Fluid configuration
+   * @param {number} load - Load value
+   * @param {number} [price] - Price if exist
+   * @returns {number}
+   */
+  private applyPrice(
+    fluidConfig: FluidConfig,
+    load: number,
+    price?: number | null
+  ): number {
+    if (price) {
+      return price
+    } else {
+      return load * fluidConfig.coefficient
+    }
+  }
 }
diff --git a/src/services/performanceIndicator.service.ts b/src/services/performanceIndicator.service.ts
index 59a0143c3b5eeac2605b7852f5ee008044662f9c..63ce8945685152aa9a9137fa2252b3819212fb1e 100644
--- a/src/services/performanceIndicator.service.ts
+++ b/src/services/performanceIndicator.service.ts
@@ -17,7 +17,11 @@ export default class PerformanceIndicatorService {
         const performanceIndicator = performanceIndicators[key]
         const fluidType = parseInt(key)
         currentValue += performanceIndicator.value
-          ? converterService.LoadToEuro(performanceIndicator.value, fluidType)
+          ? converterService.LoadToEuro(
+              performanceIndicator.value,
+              fluidType,
+              performanceIndicator ? performanceIndicator.price : null
+            )
           : 0
       }
       if (
@@ -33,7 +37,8 @@ export default class PerformanceIndicatorService {
           compareValue += performanceIndicator.compareValue
             ? converterService.LoadToEuro(
                 performanceIndicator.compareValue,
-                fluidType
+                fluidType,
+                performanceIndicator ? performanceIndicator.price : null
               )
             : 0
         }
@@ -47,7 +52,11 @@ export default class PerformanceIndicatorService {
           const performanceIndicator = performanceIndicators[key]
           const fluidType = parseInt(key)
           currentValue += performanceIndicator.value
-            ? converterService.LoadToEuro(performanceIndicator.value, fluidType)
+            ? converterService.LoadToEuro(
+                performanceIndicator.value,
+                fluidType,
+                performanceIndicator ? performanceIndicator.price : null
+              )
             : 0
         }
       }
@@ -60,7 +69,8 @@ export default class PerformanceIndicatorService {
           compareValue += performanceIndicator.compareValue
             ? converterService.LoadToEuro(
                 performanceIndicator.compareValue,
-                fluidType
+                fluidType,
+                performanceIndicator ? performanceIndicator.price : null
               )
             : 0
         }
diff --git a/src/services/queryRunner.service.ts b/src/services/queryRunner.service.ts
index aef650f2ef932e2274a06e19b7a4e39200d55208..f9733ef3d9057b040d7c3347483a23ffc9f866a2 100644
--- a/src/services/queryRunner.service.ts
+++ b/src/services/queryRunner.service.ts
@@ -146,6 +146,7 @@ export default class QueryRunner {
         keepLocalTime: true,
       }),
       value: entry.load,
+      price: entry.price,
       valueDetail: null,
     }))
 
diff --git a/src/targets/services/fluidsPrices.ts b/src/targets/services/fluidsPrices.ts
index 02cb8b5d0cb41aeda1b8b0406b0389ecb85e07f2..d5596a881d9d1e126418911aae520a66f962bf98 100644
--- a/src/targets/services/fluidsPrices.ts
+++ b/src/targets/services/fluidsPrices.ts
@@ -29,11 +29,11 @@ const getTimePeriod = async (
 ): Promise<TimePeriod> => {
   switch (timeStep) {
     case TimeStep.HALF_AN_HOUR:
-    case TimeStep.DAY:
       return {
         startDate: date,
         endDate: date.plus({ day: 1 }).startOf('day'),
       }
+    case TimeStep.DAY:
     case TimeStep.MONTH:
       return {
         startDate: date.startOf('month'),
@@ -128,12 +128,12 @@ const applyPrices = async (client: Client, fluidType: FluidType) => {
   // Prices data exsit
   if (prices.length > 0) {
     log('debug', 'fluidPrices data found')
-    const firstMinuteData = await cdm.getFirsDataDateFromDoctype(
+    const firstMinuteData = await cdm.getFirstDataDateFromDoctypeWithPrice(
       getDoctypeTypeByFluid(fluidType)
     )
 
     // If there is data, update hourly data and daily data
-    if (firstMinuteData) {
+    if (firstMinuteData && firstMinuteData.length > 0) {
       // Format first date
       const firstDate = DateTime.fromObject({
         year: firstMinuteData[0].year,
@@ -154,10 +154,10 @@ const applyPrices = async (client: Client, fluidType: FluidType) => {
               fluidType,
               date
             )
-            log(
-              'debug',
-              `Step: ${timeStep} | Fluid : ${fluidType} | Date: ${date.day}/${date.month}/${date.year} | Price: ${priceData.price}`
-            )
+            // log(
+            //   'debug',
+            //   `Step: ${timeStep} | Fluid : ${fluidType} | Date: ${date.day}/${date.month}/${date.year} | Price: ${priceData.price}`
+            // )
             const tp = await getTimePeriod(timeStep, date)
 
             // Get doc to update
@@ -176,7 +176,11 @@ const applyPrices = async (client: Client, fluidType: FluidType) => {
             }
 
             // Update date
-            date = date.plus({ days: 1 })
+            if (timeStep === TimeStep.HALF_AN_HOUR) {
+              date = date.plus({ days: 1 })
+            } else {
+              date = date.plus({ month: 1 }).startOf('month')
+            }
           } while (date < today)
           resolve()
         })
@@ -186,16 +190,17 @@ const applyPrices = async (client: Client, fluidType: FluidType) => {
 
       // Call aggregation method
       await aggregatePrices(client, qr, cdm, firstDate, today, fluidType)
-    } else log('info', 'No data found')
+    } else log('info', `No data found for fluid ${fluidType}`)
   } else log('info', 'No fluidesPrices data')
 }
 
 const processPrices = async ({ client }: PricesProps) => {
   log('info', `Processing electricity data...`)
-  await applyPrices(client, FluidType.ELECTRICITY)
+  const elec = applyPrices(client, FluidType.ELECTRICITY)
   log('info', `Electricity data done`)
   log('info', `Processing gas data...`)
-  await applyPrices(client, FluidType.GAS)
+  const gas = applyPrices(client, FluidType.GAS)
+  await Promise.all([elec, gas])
   log('info', `Gas data done`)
 }
 
diff --git a/src/types/cozy-client.d.ts b/src/types/cozy-client.d.ts
index 37bdf2ed80350ff1488f1f097880203b683efd5e..b6186859507384142c042f203c65f2ad4276aedd 100644
--- a/src/types/cozy-client.d.ts
+++ b/src/types/cozy-client.d.ts
@@ -1,371 +1,383 @@
-import * as CozyStackClient from 'cozy-stack-client'
-import { TRealtimePlugin, RealtimePlugin } from 'cozy-realtime'
-import { TDoctype } from 'doctypes'
-import { Relation } from 'models'
-
-declare module 'cozy-client' {
-  /**
-   * @typedef {object} HydratedDocument
-   */
-
-  export const CozyProvider: React.FC<{ client: Client; store?: any }>
-
-  export function useClient(): Client
-  export function Q(doctype: TDoctype): QueryDefinition
-
-  export type SortOptions = { [field: string]: 'asc' | 'desc' }
-  export type QueryDefinition = {
-    checkSortOrder(opts: {
-      sort: SortOptions
-      selector: unknown
-      indexedFields: unknown
-    }): QueryDefinition
-    getById(id: string): QueryDefinition
-    getByIds(ids: Array<string>): QueryDefinition
-    include(relations: Array<string>): QueryDefinition
-    indexFields(indexedFields: Array<string>): QueryDefinition
-    limitBy(limit: number): QueryDefinition
-    offset(skip: number): QueryDefinition
-    offsetBookmark(bookmark: string): QueryDefinition
-    offsetCursor(cursor): QueryDefinition
-    referencedBy(document: unknown): QueryDefinition
-    select(field: Array<string> | undefined): QueryDefinition
-    sortBy(sort: Array<SortOptions>): QueryDefinition
-    where(selector: MongoSelector): QueryDefinition
-  }
-  export type QueryResult<T, I = undefined> = {
-    bookmark: string
-    next: boolean
-    meta?: { count: number }
-    skip: number
-    data: T
-    included?: I
-  }
-
-  export interface MongoSelector {
-    [field: unknown]: unknown
-  }
-  export interface AllQueryOptions {
-    bookmark?: string
-    keys?: unknown
-    limit?: number
-    skip?: number
-  }
-  export interface FindQueryOptions {
-    bookmark?: string
-    fields?: Array<string>
-    indexId?: string
-    limit?: number
-    skip?: number
-    sort?: SortOptions[]
-  }
-  interface ClientInstanceOpts {
-    cozyAppEditor: string
-    cozyAppName: string
-    cozyAppNamePrefix: string
-    cozyAppSlug: string
-    cozyDomain: string
-    cozyIconPath: string
-    cozyLocale: string
-    cozyToken: string
-  }
-  interface ClientToJSON {
-    uri: string
-  }
-  interface ClientLogin {
-    token: string
-    uri: string
-  }
-  interface ClientSchema {
-    byDoctype: TDoctype
-    client: Client
-  }
-
-  export class Client {
-    appMetadata: { version: string; slug: string }
-    options: ClientLogin
-    idCounter: number
-    isLogged: boolean
-    instanceOptions: ClientInstanceOpts
-    links: unknown
-    chain: unknown
-    schema: unknown
-    plugins: { realtime: TRealtimePlugin; [key: string]: unknown }
-
-    reducer(): any
-    setStore(store: any)
-
-    /**
-     * A plugin is a class whose constructor receives the client as first argument.
-     * The main mean of interaction with the client should be with events
-     * like "login"/"logout".
-     *
-     * The plugin system is meant to encourage separation of concerns, modularity
-     * and testability : instead of registering events at module level, please
-     * create a plugin that subscribes to events.
-     *
-     * Plugin instances are stored internally in the `plugins` attribute of the client
-     * and can be accessed via this mean. A plugin class must have the attribute
-     * `pluginName` that will be use as the key in the `plugins` object.
-     *
-     * Two plugins with the same `pluginName` cannot co-exist.
-     *
-     * @example
-     * ```
-     * class AlertPlugin {
-     *   constructor(client, options) {
-     *     this.client = client
-     *     this.options = options
-     *     this.handleLogin = this.handleLogin.bind(this)
-     *     this.handleLogout = this.handleLogout.bind(this)
-     *     this.client.on("login", this.handleLogin)
-     *     this.client.on("logout", this.handleLogout)
-     *   }
-     *
-     *   handleLogin() {
-     *     alert(this.options.onLoginAlert)
-     *   }
-     *
-     *   handleLogout() {
-     *     alert(this.options.onLogoutAlert)
-     *   }
-     * }
-     *
-     * AlertPlugin.pluginName = 'alerts'
-     *
-     * client.registerPlugin(AlertPlugin, {
-     *   onLoginAlert: 'client has logged in !',
-     *   onLogoutAlert: 'client has logged out !'
-     * })
-     *
-     * // the instance of the plugin is accessible via
-     * client.plugins.alerts
-     * ```
-     */
-    registerPlugin(Plugin: RealtimePlugin | unknown, options?: unknown)
-
-    /**
-     * Notify the links that they can start and set isLogged to true.
-     *
-     * On mobile, where url/token are set after instantiation, use this method
-     * to set the token and uri via options.
-     *
-     * Emits
-     *
-     * - "beforeLogin" at the beginning, before links have been set up
-     * - "login" when the client is fully logged in and links have been set up
-     *
-     * @param  {object}   options - Options
-     * @param  {string}   options.token  - If passed, the token is set on the client
-     * @param  {string}   options.uri  - If passed, the uri is set on the client
-     * @returns {Promise} - Resolves when all links have been setup and client is fully logged in
-     *
-     */
-    login(options: ClientLogin): Promise<unknown>
-
-    /**
-     * Logs out the client and reset all the links
-     *
-     * Emits
-     *
-     * - "beforeLogout" at the beginning, before links have been reset
-     * - "login" when the client is fully logged out and links have been reset
-     *
-     * @returns {Promise} - Resolves when all links have been reset and client is fully logged out
-     */
-    logout(): Promise<unknown>
-
-    /**
-     * Forwards to a stack client instance and returns
-     * a [DocumentCollection]{@link https://docs.cozy.io/en/cozy-client/api/cozy-stack-client/#DocumentCollection} instance.
-     *
-     * @param  {string} doctype - The collection doctype.
-     * @returns {CozyStackClient.DocumentCollection} - Collection corresponding to the doctype
-     */
-    collection(doctype: TDoctype): CozyStackClient.AllCollections
-
-    /**
-     * Fetches an endpoint in an authorized way.
-     *
-     * @param  {string} method The HTTP method.
-     * @param  {string} path The URI.
-     * @param  {object} body The payload.
-     * @param  {object} opts Options for fetch
-     * @returns {Promise}
-     * @throws {FetchError}
-     */
-    fetch(
-      method: string,
-      path: string,
-      body: unknown,
-      options?: unknown
-    ): Promise<unknown>
-
-    find(doctype: string, selector?: MongoSelector): QueryDefinition
-    get(doctype: TDoctype, id: string): unknown
-    validate<D>(document: D): unknown
-    save<D, M = undefined>(
-      documentType: D,
-      mutationOptions?: M
-    ): Promise<QueryResult<T, I>>
-
-    /**
-     * Creates a list of mutations to execute to create a document and its relationships.
-     *
-     * ```js
-     * const baseDoc = { _type: 'io.cozy.todo', label: 'Go hiking' }
-     * // relations can be arrays or single objects
-     * const relationships = {
-     *   attachments: [{ _id: 12345, _type: 'io.cozy.files' }, { _id: 6789, _type: 'io.cozy.files' }],
-     *   bills: { _id: 9999, _type: 'io.cozy.bills' }
-     * }
-     * client.getDocumentSavePlan(baseDoc, relationships)
-     * ```
-     *
-     * @param  {object} document      The base document to create
-     * @param  {object} relationships The list of relationships to add, as a dictionnary. Keys should be relationship names and values the documents to link.
-     * @returns {Mutation[]}  One or more mutation to execute
-     */
-    getDocumentSavePlan<D>(document: D, relationships: unknown)
-    triggerHook<D>(name: string, document: D): unknown
-
-    /**
-     * Destroys a document. {before,after}:destroy hooks will be fired.
-     *
-     * @param  {Document} document - Document to be deleted
-     * @returns {Document} The document that has been deleted
-     */
-    destroy<D>(document: D): Promise<QueryResult<T, I>>
-    upload(file: File, dirPath: string, mutationOptions?: unknown)
-    ensureQueryExists(
-      queryId: string,
-      queryDefinition: QueryDefinition
-    ): unknown
-
-    /**
-     * Executes a query and returns its results.
-     *
-     * Results from the query will be saved internally and can be retrieved via
-     * `getQueryFromState` or directly using `<Query />`. `<Query />` automatically
-     * executes its query when mounted if no fetch policy has been indicated.
-     *
-     * @param  {QueryDefinition} queryDefinition - Definition that will be executed
-     * @param  {string} options - Options
-     * @param  {string} options.as - Names the query so it can be reused (by multiple components for example)
-     * @param  {string} options.fetchPolicy - Fetch policy to bypass fetching based on what's already inside the state. See "Fetch policies"
-     * @returns {QueryResult}
-     */
-    query(
-      queryDefinition: QueryDefinition,
-      { update, ...options }?: unknown
-    ): Promise<QueryResult<T, I>>
-
-    /**
-     * Will fetch all documents for a `queryDefinition`, automatically fetching more
-     * documents if the total of documents is superior to the pagination limit. Can
-     * result in a lot of network requests.
-     *
-     * @param  {QueryDefinition} queryDefinition - Definition to be executed
-     * @param  {object} options - Options to the query
-     * @returns {Array} All documents matching the query
-     */
-    queryAll(
-      queryDefinition: QueryDefinition,
-      options: object
-    ): Promise<QueryResult<T, I>>
-    makeObservableQuery(
-      queryDefinition: QueryDefinition,
-      options?: unknown
-    ): unknown
-    create<D>(
-      doctype: TDoctype,
-      entry: D,
-      relationships?: unknown,
-      options?: unknown
-    ): Promise<QueryResult<T, I>>
-    getStackClient(): ClientStackClient
-    getInstanceOptions(): ClientInstanceOpts
-    toJSON(): ClientToJSON
-
-    /**
-     * Returns documents with their relationships resolved according to their schema.
-     * If related documents are not in the store, they will not be fetched automatically.
-     * Instead, the relationships will have null documents.
-     *
-     * @param  {string} doctype - Doctype of the documents being hydrated
-     * @param  {Array<Document>} documents - Documents to be hydrated
-     * @returns {Array<HydratedDocument>}
-     */
-    hydrateDocuments<D>(
-      doctype: TDoctype,
-      documents: Array<D>
-    ): Array<HydratedDocument>
-
-    /**
-     * Resolves relationships on a document.
-     *
-     * The original document is kept in the target attribute of
-     * the relationship
-     *
-     * @param  {Document} document for which relationships must be resolved
-     * @param  {Schema} schemaArg for the document doctype
-     * @returns {HydratedDocument}
-     */
-    hydrateDocument<D>(document: D, schemaArg?: TDoctype): HydratedDocument
-  }
-
-  class CCozyClient {
-    constructor(n: unknown): Client
-  }
-  const CozyClient: {
-    new (n: unknown): Client
-  } = CCozyClient
-  export default CozyClient
-
-  export type HydratedDoc = any
-
-  // FIX BEGIN :: Types temporary
-  export class HasMany {
-    /**
-     * Sets a relationship item with the relationship name and id
-     *
-     * @param {object} doc - Document to be updated
-     * @param {string} relName - Name of the relationship
-     * @param {string} relItemId - Id of the relationship item
-     * @param {object} relItemAttrs - Attributes to be set (at least _id and _type)
-     */
-    static setHasManyItem<D, R>(
-      doc: D,
-      relName: string,
-      relItemId: string,
-      relItemAttrs: Relation
-    ): R
-
-    /**
-     * Gets a relationship item with the relationship name and id
-     *
-     * @param {object} doc - Document to be updated
-     * @param {string} relName - Name of the relationship
-     * @param {string} relItemId - Id of the relationship item
-     */
-    static getHasManyItem<D, R>(doc: D, relName: string, relItemId: string): R
-
-    /**
-     * Updates a relationship item with the relationship name and id
-     *
-     * @param {object} doc - Document to be updated
-     * @param {string} relName - Name of the relationship
-     * @param {string} relItemId - Id of the relationship item
-     * @param {Function} updater - receives the current relationship item and should
-     * return an updated version. Merge should be used in the updater
-     * if previous relationship item fields are to be kept.
-     */
-    static updateHasManyItem<D, R>(
-      doc: D,
-      relName: string,
-      relItemId: string,
-      updater: (relItem: Relation) => Relation
-    ): Promise<QueryResult<R>>
-  }
-  // FIX END
-}
+import * as CozyStackClient from 'cozy-stack-client'
+import { TRealtimePlugin, RealtimePlugin } from 'cozy-realtime'
+import { TDoctype } from 'doctypes'
+import { Relation } from 'models'
+
+declare module 'cozy-client' {
+  /**
+   * @typedef {object} HydratedDocument
+   */
+
+  export const CozyProvider: React.FC<{ client: Client; store?: any }>
+
+  export function useClient(): Client
+  export function Q(doctype: TDoctype): QueryDefinition
+
+  export type SortOptions = { [field: string]: 'asc' | 'desc' }
+  export type QueryDefinition = {
+    checkSortOrder(opts: {
+      sort: SortOptions
+      selector: unknown
+      indexedFields: unknown
+    }): QueryDefinition
+    getById(id: string): QueryDefinition
+    getByIds(ids: Array<string>): QueryDefinition
+    include(relations: Array<string>): QueryDefinition
+    indexFields(indexedFields: Array<string>): QueryDefinition
+    partialIndex(partialFilter: object): QueryDefinition
+    limitBy(limit: number): QueryDefinition
+    offset(skip: number): QueryDefinition
+    offsetBookmark(bookmark: string): QueryDefinition
+    offsetCursor(cursor): QueryDefinition
+    referencedBy(document: unknown): QueryDefinition
+    select(field: Array<string> | undefined): QueryDefinition
+    sortBy(sort: Array<SortOptions>): QueryDefinition
+    where(selector: MongoSelector): QueryDefinition
+  }
+  export type QueryResult<T, I = undefined> = {
+    bookmark: string
+    next: boolean
+    meta?: { count: number }
+    skip: number
+    data: T
+    included?: I
+  }
+
+  export interface MongoSelector {
+    [field: unknown]: unknown
+  }
+  export interface AllQueryOptions {
+    bookmark?: string
+    keys?: unknown
+    limit?: number
+    skip?: number
+  }
+  export interface FindQueryOptions {
+    bookmark?: string
+    fields?: Array<string>
+    indexId?: string
+    limit?: number
+    skip?: number
+    sort?: SortOptions[]
+  }
+  interface ClientInstanceOpts {
+    cozyAppEditor: string
+    cozyAppName: string
+    cozyAppNamePrefix: string
+    cozyAppSlug: string
+    cozyDomain: string
+    cozyIconPath: string
+    cozyLocale: string
+    cozyToken: string
+  }
+  interface ClientToJSON {
+    uri: string
+  }
+  interface ClientLogin {
+    token: string
+    uri: string
+  }
+  interface ClientSchema {
+    byDoctype: TDoctype
+    client: Client
+  }
+
+  export class Client {
+    appMetadata: { version: string; slug: string }
+    options: ClientLogin
+    idCounter: number
+    isLogged: boolean
+    instanceOptions: ClientInstanceOpts
+    links: unknown
+    chain: unknown
+    schema: unknown
+    plugins: { realtime: TRealtimePlugin; [key: string]: unknown }
+
+    reducer(): any
+    setStore(store: any)
+
+    /**
+     * A plugin is a class whose constructor receives the client as first argument.
+     * The main mean of interaction with the client should be with events
+     * like "login"/"logout".
+     *
+     * The plugin system is meant to encourage separation of concerns, modularity
+     * and testability : instead of registering events at module level, please
+     * create a plugin that subscribes to events.
+     *
+     * Plugin instances are stored internally in the `plugins` attribute of the client
+     * and can be accessed via this mean. A plugin class must have the attribute
+     * `pluginName` that will be use as the key in the `plugins` object.
+     *
+     * Two plugins with the same `pluginName` cannot co-exist.
+     *
+     * @example
+     * ```
+     * class AlertPlugin {
+     *   constructor(client, options) {
+     *     this.client = client
+     *     this.options = options
+     *     this.handleLogin = this.handleLogin.bind(this)
+     *     this.handleLogout = this.handleLogout.bind(this)
+     *     this.client.on("login", this.handleLogin)
+     *     this.client.on("logout", this.handleLogout)
+     *   }
+     *
+     *   handleLogin() {
+     *     alert(this.options.onLoginAlert)
+     *   }
+     *
+     *   handleLogout() {
+     *     alert(this.options.onLogoutAlert)
+     *   }
+     * }
+     *
+     * AlertPlugin.pluginName = 'alerts'
+     *
+     * client.registerPlugin(AlertPlugin, {
+     *   onLoginAlert: 'client has logged in !',
+     *   onLogoutAlert: 'client has logged out !'
+     * })
+     *
+     * // the instance of the plugin is accessible via
+     * client.plugins.alerts
+     * ```
+     */
+    registerPlugin(Plugin: RealtimePlugin | unknown, options?: unknown)
+
+    /**
+     * Notify the links that they can start and set isLogged to true.
+     *
+     * On mobile, where url/token are set after instantiation, use this method
+     * to set the token and uri via options.
+     *
+     * Emits
+     *
+     * - "beforeLogin" at the beginning, before links have been set up
+     * - "login" when the client is fully logged in and links have been set up
+     *
+     * @param  {object}   options - Options
+     * @param  {string}   options.token  - If passed, the token is set on the client
+     * @param  {string}   options.uri  - If passed, the uri is set on the client
+     * @returns {Promise} - Resolves when all links have been setup and client is fully logged in
+     *
+     */
+    login(options: ClientLogin): Promise<unknown>
+
+    /**
+     * Logs out the client and reset all the links
+     *
+     * Emits
+     *
+     * - "beforeLogout" at the beginning, before links have been reset
+     * - "login" when the client is fully logged out and links have been reset
+     *
+     * @returns {Promise} - Resolves when all links have been reset and client is fully logged out
+     */
+    logout(): Promise<unknown>
+
+    /**
+     * Forwards to a stack client instance and returns
+     * a [DocumentCollection]{@link https://docs.cozy.io/en/cozy-client/api/cozy-stack-client/#DocumentCollection} instance.
+     *
+     * @param  {string} doctype - The collection doctype.
+     * @returns {CozyStackClient.DocumentCollection} - Collection corresponding to the doctype
+     */
+    collection(doctype: TDoctype): CozyStackClient.AllCollections
+
+    /**
+     * Fetches an endpoint in an authorized way.
+     *
+     * @param  {string} method The HTTP method.
+     * @param  {string} path The URI.
+     * @param  {object} body The payload.
+     * @param  {object} opts Options for fetch
+     * @returns {Promise}
+     * @throws {FetchError}
+     */
+    fetch(
+      method: string,
+      path: string,
+      body: unknown,
+      options?: unknown
+    ): Promise<unknown>
+
+    find(doctype: string, selector?: MongoSelector): QueryDefinition
+    get(doctype: TDoctype, id: string): unknown
+    validate<D>(document: D): unknown
+    save<D, M = undefined>(
+      documentType: D,
+      mutationOptions?: M
+    ): Promise<QueryResult<T, I>>
+
+    /**
+     * Saves multiple documents in one batch
+     * - Can only be called with documents from the same doctype
+     * - Does not support automatic creation of references
+     *
+     * @param  {CozyClientDocument[]} docs
+     * @param  {Object} mutationOptions
+     * @returns {Promise<void>}
+     */
+    saveAll(docs: D[], mutationOptions?: any): Promise<QueryResult<T, I>>
+
+    /**
+     * Creates a list of mutations to execute to create a document and its relationships.
+     *
+     * ```js
+     * const baseDoc = { _type: 'io.cozy.todo', label: 'Go hiking' }
+     * // relations can be arrays or single objects
+     * const relationships = {
+     *   attachments: [{ _id: 12345, _type: 'io.cozy.files' }, { _id: 6789, _type: 'io.cozy.files' }],
+     *   bills: { _id: 9999, _type: 'io.cozy.bills' }
+     * }
+     * client.getDocumentSavePlan(baseDoc, relationships)
+     * ```
+     *
+     * @param  {object} document      The base document to create
+     * @param  {object} relationships The list of relationships to add, as a dictionnary. Keys should be relationship names and values the documents to link.
+     * @returns {Mutation[]}  One or more mutation to execute
+     */
+    getDocumentSavePlan<D>(document: D, relationships: unknown)
+    triggerHook<D>(name: string, document: D): unknown
+
+    /**
+     * Destroys a document. {before,after}:destroy hooks will be fired.
+     *
+     * @param  {Document} document - Document to be deleted
+     * @returns {Document} The document that has been deleted
+     */
+    destroy<D>(document: D): Promise<QueryResult<T, I>>
+    upload(file: File, dirPath: string, mutationOptions?: unknown)
+    ensureQueryExists(
+      queryId: string,
+      queryDefinition: QueryDefinition
+    ): unknown
+
+    /**
+     * Executes a query and returns its results.
+     *
+     * Results from the query will be saved internally and can be retrieved via
+     * `getQueryFromState` or directly using `<Query />`. `<Query />` automatically
+     * executes its query when mounted if no fetch policy has been indicated.
+     *
+     * @param  {QueryDefinition} queryDefinition - Definition that will be executed
+     * @param  {string} options - Options
+     * @param  {string} options.as - Names the query so it can be reused (by multiple components for example)
+     * @param  {string} options.fetchPolicy - Fetch policy to bypass fetching based on what's already inside the state. See "Fetch policies"
+     * @returns {QueryResult}
+     */
+    query(
+      queryDefinition: QueryDefinition,
+      { update, ...options }?: unknown
+    ): Promise<QueryResult<T, I>>
+
+    /**
+     * Will fetch all documents for a `queryDefinition`, automatically fetching more
+     * documents if the total of documents is superior to the pagination limit. Can
+     * result in a lot of network requests.
+     *
+     * @param  {QueryDefinition} queryDefinition - Definition to be executed
+     * @param  {object} options - Options to the query
+     * @returns {Array} All documents matching the query
+     */
+    queryAll(
+      queryDefinition: QueryDefinition,
+      options: object
+    ): Promise<QueryResult<T, I>>
+    makeObservableQuery(
+      queryDefinition: QueryDefinition,
+      options?: unknown
+    ): unknown
+    create<D>(
+      doctype: TDoctype,
+      entry: D,
+      relationships?: unknown,
+      options?: unknown
+    ): Promise<QueryResult<T, I>>
+    getStackClient(): ClientStackClient
+    getInstanceOptions(): ClientInstanceOpts
+    toJSON(): ClientToJSON
+
+    /**
+     * Returns documents with their relationships resolved according to their schema.
+     * If related documents are not in the store, they will not be fetched automatically.
+     * Instead, the relationships will have null documents.
+     *
+     * @param  {string} doctype - Doctype of the documents being hydrated
+     * @param  {Array<Document>} documents - Documents to be hydrated
+     * @returns {Array<HydratedDocument>}
+     */
+    hydrateDocuments<D>(
+      doctype: TDoctype,
+      documents: Array<D>
+    ): Array<HydratedDocument>
+
+    /**
+     * Resolves relationships on a document.
+     *
+     * The original document is kept in the target attribute of
+     * the relationship
+     *
+     * @param  {Document} document for which relationships must be resolved
+     * @param  {Schema} schemaArg for the document doctype
+     * @returns {HydratedDocument}
+     */
+    hydrateDocument<D>(document: D, schemaArg?: TDoctype): HydratedDocument
+  }
+
+  class CCozyClient {
+    constructor(n: unknown): Client
+  }
+  const CozyClient: {
+    new (n: unknown): Client
+  } = CCozyClient
+  export default CozyClient
+
+  export type HydratedDoc = any
+
+  // FIX BEGIN :: Types temporary
+  export class HasMany {
+    /**
+     * Sets a relationship item with the relationship name and id
+     *
+     * @param {object} doc - Document to be updated
+     * @param {string} relName - Name of the relationship
+     * @param {string} relItemId - Id of the relationship item
+     * @param {object} relItemAttrs - Attributes to be set (at least _id and _type)
+     */
+    static setHasManyItem<D, R>(
+      doc: D,
+      relName: string,
+      relItemId: string,
+      relItemAttrs: Relation
+    ): R
+
+    /**
+     * Gets a relationship item with the relationship name and id
+     *
+     * @param {object} doc - Document to be updated
+     * @param {string} relName - Name of the relationship
+     * @param {string} relItemId - Id of the relationship item
+     */
+    static getHasManyItem<D, R>(doc: D, relName: string, relItemId: string): R
+
+    /**
+     * Updates a relationship item with the relationship name and id
+     *
+     * @param {object} doc - Document to be updated
+     * @param {string} relName - Name of the relationship
+     * @param {string} relItemId - Id of the relationship item
+     * @param {Function} updater - receives the current relationship item and should
+     * return an updated version. Merge should be used in the updater
+     * if previous relationship item fields are to be kept.
+     */
+    static updateHasManyItem<D, R>(
+      doc: D,
+      relName: string,
+      relItemId: string,
+      updater: (relItem: Relation) => Relation
+    ): Promise<QueryResult<R>>
+  }
+  // FIX END
+}