diff --git a/rfc/0004_ws2p_v1.md b/rfc/0004_ws2p_v1.md
index dd99566b9e8543b2d3d1430b10a0ae6b3db8826e..5460ad9cc84c27905a5df1e0a3063721feda1c38 100644
--- a/rfc/0004_ws2p_v1.md
+++ b/rfc/0004_ws2p_v1.md
@@ -5,6 +5,8 @@ This document details the current specifications of WS2P v1 as they are already
 ## Contents
 
 * [Contents](#contents)
+* [Conventions](#conventions)
+  * [JSON format](#json-format)
 * [What is WS2P ?](#what-is-ws2p-)
 * [WS2P Endpoints](#ws2p-endpoints)
   * [Endpoint format](#endpoint-format)
@@ -26,6 +28,28 @@ This document details the current specifications of WS2P v1 as they are already
   * [getRequirementsPending](#getrequirementspending)
   * [List of error messages](#list-of-error-messages)
 
+## Conventions
+
+### JSON format
+
+All data in JSON format is presented in this RFC with explicit typing.
+
+Types list : 
+
+    Number(field description),
+    String(field description),
+    Bool(field description),
+    Object(field description)
+
+Example : 
+
+    {
+        "pubkey": String(identity pubkey in base58),
+        "expires_on": Number(timestamp),
+        "wasMember": Bool(true if the identity has already been a member at least once),
+        "pendingMembership" : Object(pending membership document)
+    ]
+
 
 ## What is WS2P ?
 
@@ -119,15 +143,15 @@ for each connection attempt, the process is as follows:
 JSON format :
 
     {
-        auth: 'CONNECT',
-        pub: "D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx",
-        challenge: "28170b84-3468-4c21-806e-cf6457d43298055df085-8e5e-43cd-9907-e5c4f9de5bc7",
-        sig: "wIa/gohWYcJUt10xgsMAjlBiMYhxu2DOKDJdPiEFVB3OVynFvPPW4S/gGZQE7vlxzplSHUE3dCSWfrtjGtlGCw=="
+        "auth": String("CONNECT"),
+        "pub": String("D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx"),
+        "challenge": String("28170b84-3468-4c21-806e-cf6457d43298055df085-8e5e-43cd-9907-e5c4f9de5bc7"),
+        "sig": String("wIa/gohWYcJUt10xgsMAjlBiMYhxu2DOKDJdPiEFVB3OVynFvPPW4S/gGZQE7vlxzplSHUE3dCSWfrtjGtlGCw==")
     }
     
-pub : Local node public key  
-challenge: random string  
-sig:  ed25519 signature of the RAW format message in base64.
+pub := Local node public key  
+challenge := random string  
+sig := ed25519 signature of the RAW format message in base64.
 
 RAW format : `WS2P:CONNECT:currency_name:pub:challenge`
 
@@ -138,13 +162,13 @@ RAW format of the example message above : `WS2P:CONNECT:g1:D9D2zaJoWYWveii1JRYLV
 JSON format :
 
     {
-        auth: 'ACK',
-        pub: "D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx",
-        sig: "wIa/gohWYcJUt10xgsMAjlBiMYhxu2DOKDJdPiEFVB3OVynFvPPW4S/gGZQE7vlxzplSHUE3dCSWfrtjGtlGCw=="
+        "auth": String("ACK"),
+        "pub": String("D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx"),
+        "sig": String("wIa/gohWYcJUt10xgsMAjlBiMYhxu2DOKDJdPiEFVB3OVynFvPPW4S/gGZQE7vlxzplSHUE3dCSWfrtjGtlGCw==")
     }
     
-pub : Local node public key  
-sig:  ed25519 signature of the RAW format message in base64.
+pub := Local node public key  
+sig := ed25519 signature of the RAW format message in base64.
     
 raw format : `WS2P:ACK:currency_name:pub:challenge`
 
@@ -158,12 +182,10 @@ The challenge is not retransmitted in json format of ACK messages because the re
 JSON format :
 
     {
-        auth: 'OK',
-        sig
+        "auth: String("OK"),
+        "sig": String(ed25519 signature of the RAW format message in base64)
     }
     
-sig:  ed25519 signature of the RAW format message in base64.
-    
 raw format : `WS2P:OK:currency_name:pub:challenge`
 
 _**Be careful**, this time each one signs his message OK with his own challenge that he sent in his message CONNECT.
@@ -208,8 +230,8 @@ Each new head received from the same node overwrites the previous head in memory
 Accepted since duniter-ts **v1.6.0**
 
     {
-        message : "API:MESSAGE_TYPE:PUBKEY:BLOCKSTAMP",
-        sig : "ZkatBTCYlp1KC/AS2TcDUYmxsWo0SaIDgkTZnhJzT2HU2OdJTqYr5s5JA+8iGCf0Qml8UgiwidscAEyeEl+WBg==""
+        "message": String("API:MESSAGE_TYPE:PUBKEY:BLOCKSTAMP"),
+        "sig": String("ZkatBTCYlp1KC/AS2TcDUYmxsWo0SaIDgkTZnhJzT2HU2OdJTqYr5s5JA+8iGCf0Qml8UgiwidscAEyeEl+WBg=="")
     }
     
 #### message field
@@ -228,8 +250,8 @@ sig: ed25519 signature of the message field in base64.
 Accepted since duniter-ts **v1.6.9**
 
     {
-        message : "API:MESSAGE_TYPE:1:PUBKEY:BLOCKSTAMP:WS2PID:SOFTWARE:SOFT_VERSION:POW_PREFIX,
-        sig :"MY90zXICfbYhLlz8VrL4HWPkphZEFR+bT2JWsoKdDMadgn0R0ZjsowDsnlfNqX4F4qeWeFoxhvdVgTO9VSghCA=="
+        "message": String("API:MESSAGE_TYPE:1:PUBKEY:BLOCKSTAMP:WS2PID:SOFTWARE:SOFT_VERSION:POW_PREFIX"),
+        "sig": String("MY90zXICfbYhLlz8VrL4HWPkphZEFR+bT2JWsoKdDMadgn0R0ZjsowDsnlfNqX4F4qeWeFoxhvdVgTO9VSghCA==")
     }
     
 #### message field
@@ -253,11 +275,11 @@ Accepted since duniter-ts **v1.6.9**, relayed fully since duniter-ts **v1.6.15**
 _Nodes with versions lower than 1.6.15 bounce a degraded version of the head, only `message` and `sig` fields are relayed._
 
     {
-        message : "API:HEAD:1:PUBKEY:BLOCKSTAMP:WS2PID:SOFTWARE:SOFT_VERSION:POW_PREFIX,
-        sig : "TPh2A3NS8cHj8yrJk1Yeldx2H6bPEp46cFAGZXKfxJcNgXL2sWrlirhIOlp8pkUFSrwDawWY1zO1jlgUqMvlAg==",
-        messageV2: "API:HEAD:2:PUBKEY:BLOCKSTAMP:WS2PID:SOFTWARE:SOFT_VERSION:POW_PREFIX:FREE_MEMBER_ROOM:FREE_MIRROR_ROOM",
-        sigV2: "ta1lRrWsjGcYHcLdS75JgEW5B8ByRetFVUVVpakKNJBirhRe8HcYUHEOM7xj/+gUQGGOit6Gm5Q/lsvfsngWAQ==",
-        step: 0
+        "message": String("API:HEAD:1:PUBKEY:BLOCKSTAMP:WS2PID:SOFTWARE:SOFT_VERSION:POW_PREFIX"),
+        "sig": String("TPh2A3NS8cHj8yrJk1Yeldx2H6bPEp46cFAGZXKfxJcNgXL2sWrlirhIOlp8pkUFSrwDawWY1zO1jlgUqMvlAg=="),
+        "messageV2": String("API:HEAD:2:PUBKEY:BLOCKSTAMP:WS2PID:SOFTWARE:SOFT_VERSION:POW_PREFIX:FREE_MEMBER_ROOM:FREE_MIRROR_ROOM"),
+        "sigV2": String("ta1lRrWsjGcYHcLdS75JgEW5B8ByRetFVUVVpakKNJBirhRe8HcYUHEOM7xj/+gUQGGOit6Gm5Q/lsvfsngWAQ=="),
+        "step": Number(0)
     }
     
 #### message & messageV2 fields
@@ -315,8 +337,8 @@ All documents are sent in json format, the body format of the request is always
 
     {
         body: {
-            name: DOCUMENT_TYPE_ID,
-            [DOCUMENT_TYPE_NAME]: DOCUMENT_IN_JSON_FORMAT
+            name: Number(DOCUMENT_TYPE_ID),
+            "DOCUMENT_TYPE_NAME": Object(DOCUMENT)
         }
     }
     
@@ -335,18 +357,18 @@ With the exception of the peer format detailed below, the json format of each do
 ### Peer format
 
     {
-      "version": 10,
-      "currency": CURRENCY_NAME,
+      "version": Number(10),
+      "currency": String(CURRENCY_NAME),
       "endpoints": [
-        ENDPOINT1,
-        ENDPOINT2,
-        ENDPOINT3
+        String(ENDPOINT_1),
+        String(ENDPOINT_2),
+       ...
       ],
-      "status": "UP",
-      "block": BLOCKSTAMP,
-      "signature": SIGNATURE,
-      "raw": RAW_FORMAT,
-      "pubkey": PUBKEY
+      "status": String("UP"),
+      "block": String(BLOCKSTAMP),
+      "signature": String(SIGNATURE),
+      "raw": String(RAW_FORMAT),
+      "pubkey": String(PUBKEY)
     }
 
 Real example :
@@ -413,16 +435,16 @@ If all conditions are satisfied, then the document is saved in the local bdd of
 
 Specific queries can be sent via ws2p to obtain specific blocks or sandbox data.
 
-Each type of query has a unique identifier called "name" (Realy it's an integer).
+Each type of query has a unique identifier called "name".
 
 ### getCurrent
 
 JSON Message : 
 
     {
-        reqId: REQUESTS_UNIQUE_ID,
+        reqId: String(REQUESTS_UNIQUE_ID),
         body: {
-            name: "CURRENT",
+            name: String("CURRENT"),
             params: {}
         }
     }
@@ -433,15 +455,15 @@ it allows the requester node to identify to which query the answers it receives
 JSON response to success :
 
     {
-        resId: REQUESTS_UNIQUE_ID,
-        body: BLOCK_IN_JSON_FORMAT
+        resId: String(REQUESTS_UNIQUE_ID),
+        body: Object(BLOCK_IN_JSON_FORMAT)
     }
 
 JSON error response :
 
     {
-        resId: REQUESTS_UNIQUE_ID,
-        err: error_message_in_string_format
+        resId: String(REQUESTS_UNIQUE_ID),
+        err: String(error message)
     }
 
 ### getBlock
@@ -449,11 +471,11 @@ JSON error response :
 JSON Message : 
 
     {
-        reqId: REQUESTS_UNIQUE_ID,
+        reqId: String(REQUESTS_UNIQUE_ID),
         body: {
-            name: "BLOCK_BY_NUMBER",
+            name: String("BLOCK_BY_NUMBER"),
             params: {
-                number: BLOCK_NUMBER
+                number: Number(BLOCK_NUMBER)
             }
         }
     }
@@ -464,15 +486,15 @@ it allows the requester node to identify to which query the answers it receives
 JSON response to success :
 
     {
-        resId: REQUESTS_UNIQUE_ID,
-        body: BLOCK_IN_JSON_FORMAT
+        resId: String(REQUESTS_UNIQUE_ID),
+        body: Object(BLOCK)
     }
 
 JSON error response :
 
     {
-        resId: REQUESTS_UNIQUE_ID,
-        err: error_message_in_string_format
+        resId: String(REQUESTS_UNIQUE_ID),
+        err: String(error message)
     }
 
 ### getBlocks
@@ -484,8 +506,8 @@ JSON Message :
         body: {
             name: "BLOCKS_CHUNK",
             params: {
-                count: *number of blocks requested*,
-                fromNumber: *number of the 1st block of the requested interval*
+                count: Number(number of blocks requested),
+                fromNumber: Number(number of the 1st block of the requested interval)
             }
         }
     }
@@ -496,10 +518,10 @@ it allows the requester node to identify to which query the answers it receives
 JSON response to success :
 
     {
-        resId: REQUESTS_UNIQUE_ID,
+        resId: String(REQUESTS_UNIQUE_ID),
         body: [
-            BLOCK_1_IN_JSON_FORMAT,
-            BLOCK_2_IN_JSON_FORMAT,
+            Object(BLOCK_1),
+            Object(BLOCK_2),
             ...
         ]
     }
@@ -507,8 +529,8 @@ JSON response to success :
 JSON error response :
 
     {
-        resId: REQUESTS_UNIQUE_ID,
-        err: *error message in string format*
+        resId: String(REQUESTS_UNIQUE_ID),
+        err: String(error message)
     }
 
 ### getRequirementsPending
@@ -518,11 +540,11 @@ Requests the "requirements" of all identities that have received at least `minCe
 JSON Message : 
 
     {
-        reqId: REQUESTS_UNIQUE_ID,
+        reqId: String(REQUEST_UNIQUE_ID),
         body: {
-            name: "WOT_REQUIREMENTS_OF_PENDING",
+            name: String("WOT_REQUIREMENTS_OF_PENDING"),
             params: {
-                minCert: *integer*
+                minCert: Number()
             }
         }
     }
@@ -533,44 +555,89 @@ it allows the requester node to identify to which query the answers it receives
 JSON response to success :
 
     {
-        resId: REQUESTS_UNIQUE_ID,
-        body: {
-            identities: [
+        "resId": REQUESTS_UNIQUE_ID,
+        "body": {
+            "identities": [
                 {
-                    hash: IDTY1_HASH,
-                    member: *boolean*,
-                    wasMember: *boolean*,
-                    pubkey: IDTY1_PUBKEY,
-                    uid: IDTY1_UID,
-                    buid: IDTY1_BUID,
-                    sig: IDTY1_SIG,
-                    revocation_sig: IDTY1_REVOCATION_SIG,
-                    revoked: *boolean*,
-                    revoked_on: *integer*
+                    "certifications": [
+			            {
+                            "expiresIn": Number(timestamp),
+                            "from": String(issuer pubkey in base58),
+                            "timestamp": Number(),
+                            "to": String(receiver pubkey in base58)
+                        }),
+                        ...
+                    ]
+                    "expired": Bool(),
+                    "isSentry": Bool(),
+                    "membershipExpiresIn": Number(),
+                    "membershipPendingExpiresInm": Number(),
+                    "meta": {
+                        "timestamp": String(identity document creation blockstamp)
+                    },
+                    "outdistanced": Bool(),
+                    "pendingCerts": [
+                        {
+                            "block": Number(doubloon with "block_number" field),
+                            "block_hash": String(certification document creation block hash),
+                            "block_number": Number(certification document creation block number),
+                            "blockstamp": String(certification document creation blockstamp),
+                            "expired": Number(is always zero),
+                            "expires_on": Number(timestamp),
+                            "from": String(issuer pubkey in base58),
+                            "linked": Bool(is always false),
+                            "sig": String(certification document signature in base64),
+                            "target": String(hash of the target identity),
+                            "to": String(receiver pubkey in base58),
+                            "written": Bool(is always false),
+                            "written_block": is always Null,
+                            "written_hash": is always Null
+                        },
+                        Object(PEDNIGN_CERT_2),
+                        ...
+                    ],
+                    "pendingMemberships": [
+                        {
+                            "block": String(doubloon with "blockstamp" field),
+                            "blockHash": String(membership document creation block hash),
+                            "blockNumber": Number(99156),
+                            "blockstamp": String(membership document creation blockstamp),
+                            "certts": String(doubloon with "blockstamp" field),
+                            "expired": Null,
+                            "expires_on": Number(timestamp),
+                            "fpr": String(doubloon with "blockHash" field),
+                            "idtyHash": String(hash of the target identity),
+                            "issuer": String(issuer pubkey in base58),
+                            "membership": String(user request type : "IN" or "OUT"),
+                            "number": Number(doubloon with "blockNumber" field),
+                            "sig": String(membership document signature in base64),
+                            "signature": String(doubloon with "sig" field),
+                            "type": String(doubloon with "membership" field),
+                            "userid": String(),
+                            "written": Bool(is always false),
+                            "written_number": Null
+                        },
+                        ...
+                    ],
+                    "pubkey": String(identity pubkey in base58),
+                    "revocation_sig": String(revocation document signature in base64, empty where the identity is not revoked),
+                    "revoked": Bool(),
+                    "revoked_on": Number(?),
+                    "sig":String(identity document signature in base64),
+                    "uid": String(),
+                    "wasMember": Bool(true if the identity has already been a member at least once)
                 },
-                IDTY2,
+                Object(IDTY_2),
                 ...
             ]
         }
     }
 
-Fields details: 
-hash := sha256 of the identity document.
-member := `true` if the identity is a member, `false` otherwise.
-wasMember := `true` if the identity has already been a member at least once in the past, `false` otherwise.
-pubkey := public key ed25519 of the identity
-uid := Human name of identity
-buid := identity document creation blockstamp
-sig := signature of the identity document
-revocation_sig := signature of revocation document (empty string if the revocation document has not been published)
-revoked := `true` if the member has been revoked, `false` otherwise.
-revoked_on := Blockstamp when identity was revoked, or `0` if identity has not yet been revoked.
-
 JSON error response :
 
     {
-        resId: REQUESTS_UNIQUE_ID,
-        err: *error message in string format*
+        resId: String(REQUESTS_UNIQUE_ID),
+        err: String(error message)
     }
 
 ### List of error messages