diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/elasticsearch/MessageRecord.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/elasticsearch/MessageRecord.java
index 660ea84985b7be84c54bcd04315a4b39a2f688cf..b58b05ad9e8943104d416b4b846ba410f6185cfa 100644
--- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/elasticsearch/MessageRecord.java
+++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/elasticsearch/MessageRecord.java
@@ -28,10 +28,12 @@ package org.duniter.core.client.model.elasticsearch;
 public class MessageRecord extends Record {
 
     public static final String PROPERTY_TIME="time";
-    public static final String PROPERTY_MESSAGE="message";
+    public static final String PROPERTY_CONTENT="content";
+    public static final String PROPERTY_RECIPIENT="recipient";
 
     private Integer time;
-    private String message;
+    private String content;
+    private String recipient;
 
     public Integer getTime() {
         return time;
@@ -41,11 +43,19 @@ public class MessageRecord extends Record {
         this.time = time;
     }
 
-    public String getMessage() {
-        return message;
+    public String getContent() {
+        return content;
     }
 
-    public void setMessage(String message) {
-        this.message = message;
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public String getRecipient() {
+        return recipient;
+    }
+
+    public void setRecipient(String recipient) {
+        this.recipient = recipient;
     }
 }
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/PluginSettings.java b/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/PluginSettings.java
index 9590391789b7eeadd6c7c4b44b293802a72ba436..904c834a02c07352811e61d0dc3d94420adf80cb 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/PluginSettings.java
+++ b/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/PluginSettings.java
@@ -209,6 +209,22 @@ public class PluginSettings extends AbstractLifecycleComponent<PluginSettings> {
         return peer;
     }
 
+    public String getKeyringSalt() {
+        return settings.get("duniter.keyring.salt");
+    }
+
+    public String getKeyringPassword() {
+        return settings.get("duniter.keyring.password");
+    }
+
+    public String getKeyringPublicKey() {
+        return settings.get("duniter.keyring.pub");
+    }
+
+    public String getKeyringSecretKey() {
+        return settings.get("duniter.keyring.sec");
+    }
+
     /* protected methods */
 
     protected void initI18n() throws IOException {
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/AbstractRestPostAction.java b/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/AbstractRestPostAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..00cd50e9a3f8a8752a2addae977acdc930ff3fdb
--- /dev/null
+++ b/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/AbstractRestPostAction.java
@@ -0,0 +1,80 @@
+package org.duniter.elasticsearch.action;
+
+/*
+ * #%L
+ * duniter4j-elasticsearch-plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.duniter.core.exception.BusinessException;
+import org.duniter.elasticsearch.exception.DuniterElasticsearchException;
+import org.duniter.elasticsearch.rest.XContentThrowableRestResponse;
+import org.elasticsearch.client.Client;
+import org.elasticsearch.common.logging.ESLogger;
+import org.elasticsearch.common.logging.ESLoggerFactory;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.rest.*;
+
+import static org.elasticsearch.rest.RestRequest.Method.POST;
+import static org.elasticsearch.rest.RestStatus.OK;
+
+public abstract class AbstractRestPostAction extends BaseRestHandler {
+
+    private static ESLogger log = null;
+
+    private final JsonIndexer indexer;
+
+
+    public AbstractRestPostAction(Settings settings, RestController controller, Client client,
+                                  String indexName,
+                                  String typeName,
+                                  JsonIndexer indexer) {
+        super(settings, controller, client);
+        controller.registerHandler(POST,
+                String.format("/%s/%s", indexName, typeName),
+                this);
+        log = ESLoggerFactory.getLogger(String.format("[%s]", indexName));
+        this.indexer = indexer;
+    }
+
+    @Override
+    protected void handleRequest(final RestRequest request, RestChannel restChannel, Client client) throws Exception {
+
+        try {
+            String recordId = indexer.handleJson(request.content().toUtf8());
+
+            restChannel.sendResponse(new BytesRestResponse(OK, recordId));
+        }
+        catch(DuniterElasticsearchException | BusinessException e) {
+            log.error(e.getMessage(), e);
+            restChannel.sendResponse(new XContentThrowableRestResponse(request, e));
+        }
+        catch(Exception e) {
+            log.error(e.getMessage(), e);
+        }
+    }
+
+
+    public interface JsonIndexer {
+        String handleJson(String json) throws DuniterElasticsearchException, BusinessException;
+    }
+
+
+
+}
\ No newline at end of file
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/RestModule.java b/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/RestModule.java
index 3c674400803e00f930f18153f4492996d80291c4..c9b3bca0fc7c45ff05a9268f1e4a7edee815ff57 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/RestModule.java
+++ b/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/RestModule.java
@@ -28,6 +28,7 @@ import org.duniter.elasticsearch.action.market.RestMarketCommentIndexAction;
 import org.duniter.elasticsearch.action.market.RestMarketCommentUpdateAction;
 import org.duniter.elasticsearch.action.market.RestMarketRecordIndexAction;
 import org.duniter.elasticsearch.action.market.RestMarketRecordUpdateAction;
+import org.duniter.elasticsearch.action.message.RestMessageIndexAction;
 import org.duniter.elasticsearch.action.registry.RestRegistryRecordIndexAction;
 import org.duniter.elasticsearch.action.registry.RestRegistryRecordUpdateAction;
 import org.duniter.elasticsearch.action.security.RestSecurityAuthAction;
@@ -66,6 +67,9 @@ public class RestModule extends AbstractModule implements Module {
         // History
         bind(RestHistoryDeleteIndexAction.class).asEagerSingleton();
 
+        // Message
+        bind(RestMessageIndexAction.class).asEagerSingleton();
+
         // Cesium
         bind(RestCesiumConfigAction.class).asEagerSingleton();
 
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/message/RestMessageIndexAction.java b/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/message/RestMessageIndexAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..045bf1a285d2ab796f0a8859f743da8afd69b720
--- /dev/null
+++ b/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/message/RestMessageIndexAction.java
@@ -0,0 +1,41 @@
+package org.duniter.elasticsearch.action.message;
+
+/*
+ * #%L
+ * duniter4j-elasticsearch-plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.duniter.elasticsearch.action.AbstractRestPostAction;
+import org.duniter.elasticsearch.service.MessageService;
+import org.elasticsearch.client.Client;
+import org.elasticsearch.common.inject.Inject;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.rest.RestController;
+
+public class RestMessageIndexAction extends AbstractRestPostAction {
+
+    @Inject
+    public RestMessageIndexAction(Settings settings, RestController controller, Client client, final MessageService service) {
+        super(settings, controller, client,
+                MessageService.INDEX,
+                MessageService.RECORD_TYPE,
+                json -> service.indexRecordFromJson(json));
+    }
+}
\ No newline at end of file
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/AbstractService.java b/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/AbstractService.java
index ab820f0760d1c97daaa325f75e622332d1eaa7f9..75ae513c1a84b8d4fbee60068b8a9a267724b2f9 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/AbstractService.java
+++ b/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/AbstractService.java
@@ -175,23 +175,26 @@ public abstract class AbstractService implements Bean {
     }
 
     protected void checkSameDocumentIssuer(String index, String type, String id, String expectedIssuer) throws ElasticsearchException {
+        checkSameDocumentField(index, type, id, Record.PROPERTY_ISSUER, expectedIssuer);
+    }
+
+    protected void checkSameDocumentField(String index, String type, String id, String fieldName, String expectedvalue) throws ElasticsearchException {
 
         GetResponse response = client.prepareGet(index, type, id)
-                .setFields(Record.PROPERTY_ISSUER)
+                .setFields(fieldName)
                 .execute().actionGet();
         boolean failed = !response.isExists();
         if (failed) {
             throw new NotFoundException(String.format("Document [%s/%s/%s] not exists.", index, type, id));
         } else {
-            String docIssuer = (String)response.getFields().get(Record.PROPERTY_ISSUER).getValue();
-            if (!Objects.equals(expectedIssuer, docIssuer)) {
-                throw new AccessDeniedException(String.format("Could not delete this document: not issuer."));
+            String docValue = (String)response.getFields().get(fieldName).getValue();
+            if (!Objects.equals(expectedvalue, docValue)) {
+                throw new AccessDeniedException(String.format("Could not delete this document: not same [%s].", fieldName));
             }
         }
     }
 
 
-
     protected String getIssuer(JsonNode actualObj) {
         return  actualObj.get(Record.PROPERTY_ISSUER).asText();
     }
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/HistoryService.java b/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/HistoryService.java
index 06e9b37ac67eaed43b1d3e67d416bad5fbb3fe5e..fc3f0e4368b1c4c9bfd757e71a9711f01f2caedf 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/HistoryService.java
+++ b/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/HistoryService.java
@@ -26,6 +26,7 @@ package org.duniter.elasticsearch.service;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.JsonNode;
 import org.duniter.core.client.model.elasticsearch.DeleteRecord;
+import org.duniter.core.client.model.elasticsearch.MessageRecord;
 import org.duniter.core.exception.TechnicalException;
 import org.duniter.core.service.CryptoService;
 import org.duniter.elasticsearch.PluginSettings;
@@ -116,8 +117,14 @@ public class HistoryService extends AbstractService {
             throw new NotFoundException(String.format("Index [%s] not exists.", index));
         }
 
-        // Check document issuer
-        checkSameDocumentIssuer(index, type, id, issuer);
+        // Special case for message: check if issuer is recipient
+        if (MessageService.INDEX.equals(index)) {
+            checkSameDocumentField(index, type, id, MessageRecord.PROPERTY_RECIPIENT, issuer);
+        }
+        else {
+            // Check document issuer
+            checkSameDocumentIssuer(index, type, id, issuer);
+        }
 
         if (logger.isDebugEnabled()) {
             logger.debug(String.format("Deleting document [%s/%s/%s] - issuer [%s]", index, type, id, issuer.substring(0, 8)));
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/MarketService.java b/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/MarketService.java
index 08a8e0ac569e7b14f2d974d466ffd3a1c48e4e27..5aa804185f4fc89a0b3ff7153e0b1afe02c1924f 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/MarketService.java
+++ b/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/MarketService.java
@@ -282,6 +282,11 @@ public class MarketService extends AbstractService {
                     .field("analyzer", stringAnalyzer)
                     .endObject()
 
+                    // creationTime
+                    .startObject("creationTime")
+                    .field("type", "integer")
+                    .endObject()
+
                     // time
                     .startObject("time")
                     .field("type", "integer")
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/MessageService.java b/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/MessageService.java
index 632702c8a65ece046693d472979cac25d369b308..3dd902f50ab960bfad652d015a4fb6acf950ab70 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/MessageService.java
+++ b/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/MessageService.java
@@ -25,17 +25,10 @@ package org.duniter.elasticsearch.service;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.JsonNode;
-import com.google.common.collect.Sets;
-import com.google.gson.JsonSyntaxException;
-import org.duniter.core.client.model.elasticsearch.MessageRecord;
-import org.duniter.core.client.service.bma.WotRemoteService;
 import org.duniter.core.exception.TechnicalException;
 import org.duniter.core.service.CryptoService;
 import org.duniter.elasticsearch.PluginSettings;
-import org.duniter.elasticsearch.exception.InvalidFormatException;
-import org.duniter.elasticsearch.exception.InvalidSignatureException;
 import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder;
-import org.elasticsearch.action.index.IndexRequestBuilder;
 import org.elasticsearch.action.index.IndexResponse;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.common.inject.Inject;
@@ -44,7 +37,6 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.common.xcontent.XContentFactory;
 
 import java.io.IOException;
-import java.util.Set;
 
 /**
  * Created by Benoit on 30/03/2015.
@@ -54,8 +46,6 @@ public class MessageService extends AbstractService {
     public static final String INDEX = "message";
     public static final String RECORD_TYPE = "record";
 
-    private static final String JSON_STRING_PROPERTY_REGEX = "[,]?[\"\\s\\n\\r]*%s[\"]?[\\s\\n\\r]*:[\\s\\n\\r]*\"[^\"]+\"";
-
 
     @Inject
     public MessageService(Client client, PluginSettings settings, CryptoService cryptoService) {
@@ -118,7 +108,7 @@ public class MessageService extends AbstractService {
         String issuer = getIssuer(actualObj);
 
         if (logger.isDebugEnabled()) {
-            logger.debug(String.format("Indexing a record from issuer [%s]", issuer.substring(0, 8)));
+            logger.debug(String.format("Indexing a message from issuer [%s]", issuer.substring(0, 8)));
         }
 
         IndexResponse response = client.prepareIndex(INDEX, RECORD_TYPE)
@@ -144,56 +134,27 @@ public class MessageService extends AbstractService {
                     .field("index", "not_analyzed")
                     .endObject()
 
+                    // recipient
+                    .startObject("recipient")
+                    .field("type", "string")
+                    .field("index", "not_analyzed")
+                    .endObject()
+
                     // time
                     .startObject("time")
                     .field("type", "integer")
                     .endObject()
 
-                    // message
-                    .startObject("message")
+                    // nonce
+                    .startObject("nonce")
                     .field("type", "string")
-                    .field("analyzer", stringAnalyzer)
+                    .field("index", "not_analyzed")
                     .endObject()
 
-                    // pictures
-                    .startObject("pictures")
-                    .field("type", "nested")
-                    .field("dynamic", "false")
-                    .startObject("properties")
-                    .startObject("file") // file
-                    .field("type", "attachment")
-                    .startObject("fields")
-                    .startObject("content") // content
-                    .field("index", "no")
-                    .endObject()
-                    .startObject("title") // title
+                    // content
+                    .startObject("content")
                     .field("type", "string")
-                    .field("store", "yes")
-                    .field("analyzer", stringAnalyzer)
-                    .endObject()
-                    .startObject("author") // author
-                    .field("type", "string")
-                    .field("store", "no")
-                    .endObject()
-                    .startObject("content_type") // content_type
-                    .field("store", "yes")
-                    .endObject()
-                    .endObject()
-                    .endObject()
-                    .endObject()
-                    .endObject()
-
-                    // picturesCount
-                    .startObject("picturesCount")
-                    .field("type", "integer")
-                    .endObject()
-
-                    // tags
-                    .startObject("tags")
-                    .field("type", "completion")
-                    .field("search_analyzer", "simple")
-                    .field("analyzer", "simple")
-                    .field("preserve_separators", "false")
+                    .field("index", "not_analyzed")
                     .endObject()
 
                     .endObject()
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/RegistryService.java b/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/RegistryService.java
index 826c7efe2e39f95c84e7b8b5714cf02bb646a50d..90cab8e2360b41e0d8adb6a7aaf8caa904aeb91b 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/RegistryService.java
+++ b/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/RegistryService.java
@@ -385,6 +385,11 @@ public class RegistryService extends AbstractService {
                     .field("analyzer", stringAnalyzer)
                     .endObject()
 
+                    // creationTime
+                    .startObject("creationTime")
+                    .field("type", "integer")
+                    .endObject()
+
                     // time
                     .startObject("time")
                     .field("type", "integer")