-
Notifications
You must be signed in to change notification settings - Fork 5
/
draft-ietf-jmap-core-17.txt
4760 lines (3351 loc) · 192 KB
/
draft-ietf-jmap-core-17.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
JMAP N. Jenkins
Internet-Draft FastMail
Intended status: Standards Track C. Newman
Expires: September 19, 2019 Oracle
March 18, 2019
JSON Meta Application Protocol
draft-ietf-jmap-core-17
Abstract
This document specifies a protocol for clients to efficiently query,
fetch and modify JSON-based data objects, with support for push
notification of changes and fast resynchronisation, and out-of-band
binary data upload/download.
Status of This Memo
This Internet-Draft is submitted in full conformance with the
provisions of BCP 78 and BCP 79.
Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet-
Drafts is at https://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress."
This Internet-Draft will expire on September 19, 2019.
Copyright Notice
Copyright (c) 2019 IETF Trust and the persons identified as the
document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents
(https://trustee.ietf.org/license-info) in effect on the date of
publication of this document. Please review these documents
carefully, as they describe your rights and restrictions with respect
to this document. Code Components extracted from this document must
include Simplified BSD License text as described in Section 4.e of
the Trust Legal Provisions and are provided without warranty as
described in the Simplified BSD License.
Jenkins & Newman Expires September 19, 2019 [Page 1]
Internet-Draft JMAP March 2019
Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1. Notational conventions . . . . . . . . . . . . . . . . . 4
1.2. The Id data type . . . . . . . . . . . . . . . . . . . . 5
1.3. The Int and UnsignedInt data types . . . . . . . . . . . 6
1.4. The Date and UTCDate data types . . . . . . . . . . . . . 6
1.5. JSON as the data encoding format . . . . . . . . . . . . 6
1.6. Terminology . . . . . . . . . . . . . . . . . . . . . . . 7
1.6.1. User . . . . . . . . . . . . . . . . . . . . . . . . 7
1.6.2. Accounts . . . . . . . . . . . . . . . . . . . . . . 7
1.6.3. Data types and records . . . . . . . . . . . . . . . 7
1.7. The JMAP API model . . . . . . . . . . . . . . . . . . . 8
1.8. Vendor-specific extensions . . . . . . . . . . . . . . . 8
2. The JMAP Session resource . . . . . . . . . . . . . . . . . . 9
2.1. Example . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.2. Service autodiscovery . . . . . . . . . . . . . . . . . . 14
3. Structured data exchange . . . . . . . . . . . . . . . . . . 14
3.1. Making an API request . . . . . . . . . . . . . . . . . . 14
3.1.1. The Invocation data type . . . . . . . . . . . . . . 15
3.2. The Request object . . . . . . . . . . . . . . . . . . . 15
3.2.1. Example request . . . . . . . . . . . . . . . . . . . 16
3.3. The Response object . . . . . . . . . . . . . . . . . . . 16
3.3.1. Example response: . . . . . . . . . . . . . . . . . . 17
3.4. Omitting arguments . . . . . . . . . . . . . . . . . . . 17
3.5. Errors . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.5.1. Request-level errors . . . . . . . . . . . . . . . . 18
3.5.2. Method-level errors . . . . . . . . . . . . . . . . . 19
3.6. References to previous method results . . . . . . . . . . 21
3.7. Localisation of user-visible strings . . . . . . . . . . 25
3.8. Security . . . . . . . . . . . . . . . . . . . . . . . . 26
3.9. Concurrency . . . . . . . . . . . . . . . . . . . . . . . 26
4. The Core/echo method . . . . . . . . . . . . . . . . . . . . 26
4.1. Example . . . . . . . . . . . . . . . . . . . . . . . . . 26
5. Standard methods and naming convention . . . . . . . . . . . 26
5.1. /get . . . . . . . . . . . . . . . . . . . . . . . . . . 27
5.2. /changes . . . . . . . . . . . . . . . . . . . . . . . . 28
5.3. /set . . . . . . . . . . . . . . . . . . . . . . . . . . 31
5.4. /copy . . . . . . . . . . . . . . . . . . . . . . . . . . 36
5.5. /query . . . . . . . . . . . . . . . . . . . . . . . . . 38
5.6. /queryChanges . . . . . . . . . . . . . . . . . . . . . . 43
5.7. Examples . . . . . . . . . . . . . . . . . . . . . . . . 46
5.8. Proxy considerations . . . . . . . . . . . . . . . . . . 52
6. Binary data . . . . . . . . . . . . . . . . . . . . . . . . . 53
6.1. Uploading binary data . . . . . . . . . . . . . . . . . . 54
6.2. Downloading binary data . . . . . . . . . . . . . . . . . 55
6.3. Blob/copy . . . . . . . . . . . . . . . . . . . . . . . . 55
7. Push . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Jenkins & Newman Expires September 19, 2019 [Page 2]
Internet-Draft JMAP March 2019
7.1. The StateChange object . . . . . . . . . . . . . . . . . 57
7.1.1. Example . . . . . . . . . . . . . . . . . . . . . . . 57
7.2. PushSubscription . . . . . . . . . . . . . . . . . . . . 58
7.2.1. PushSubscription/get . . . . . . . . . . . . . . . . 60
7.2.2. PushSubscription/set . . . . . . . . . . . . . . . . 61
7.2.3. Example . . . . . . . . . . . . . . . . . . . . . . . 62
7.3. Event Source . . . . . . . . . . . . . . . . . . . . . . 64
8. Security considerations . . . . . . . . . . . . . . . . . . . 65
8.1. Transport confidentiality . . . . . . . . . . . . . . . . 65
8.2. Authentication scheme . . . . . . . . . . . . . . . . . . 66
8.3. Service autodiscovery . . . . . . . . . . . . . . . . . . 66
8.4. JSON parsing . . . . . . . . . . . . . . . . . . . . . . 66
8.5. Denial of service . . . . . . . . . . . . . . . . . . . . 67
8.6. Connection to unknown push server . . . . . . . . . . . . 67
8.7. Push encryption . . . . . . . . . . . . . . . . . . . . . 68
8.8. Traffic analysis . . . . . . . . . . . . . . . . . . . . 68
9. IANA considerations . . . . . . . . . . . . . . . . . . . . . 69
9.1. Assignment of jmap service name . . . . . . . . . . . . . 69
9.2. Registration of well-known URI suffix for JMAP . . . . . 69
9.3. Registration of the jmap URN sub-namespace . . . . . . . 69
9.4. Creation of "JMAP Capabilities" registry . . . . . . . . 70
9.4.1. Preliminary community review . . . . . . . . . . . . 70
9.4.2. Submit request to IANA . . . . . . . . . . . . . . . 71
9.4.3. Designated expert review . . . . . . . . . . . . . . 71
9.4.4. Change procedures . . . . . . . . . . . . . . . . . . 71
9.4.5. JMAP Capabilities registry template: . . . . . . . . 72
9.4.6. Initial registration for JMAP core . . . . . . . . . 72
9.4.7. Registration for JMAP error placeholder in JMAP
capabilities registry . . . . . . . . . . . . . . . . 72
9.5. Creation of "JMAP Error Codes" registry . . . . . . . . . 72
9.5.1. Designated expert review . . . . . . . . . . . . . . 73
9.5.2. JMAP Error Codes registry template: . . . . . . . . . 73
9.5.3. Initial JMAP Error Codes registry . . . . . . . . . . 74
10. References . . . . . . . . . . . . . . . . . . . . . . . . . 81
10.1. Normative References . . . . . . . . . . . . . . . . . . 81
10.2. Informative References . . . . . . . . . . . . . . . . . 85
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 85
1. Introduction
JMAP is a protocol for synchronising data, such as mail, calendars or
contacts, between a client and a server. It is optimised for mobile
and web environments, and aims to provide a consistent interface to
different data types.
This specification is for the generic mechanism of data
synchronisation. Further specifications define the data models for
different data types that may be synchronised via JMAP.
Jenkins & Newman Expires September 19, 2019 [Page 3]
Internet-Draft JMAP March 2019
JMAP is designed to make efficient use of limited network resources.
Multiple API calls may be batched in a single request to the server,
reducing round trips and improving battery life on mobile devices.
Push connections remove the need for polling, and an efficient delta
update mechanism ensures a minimum of data is transferred.
JMAP is designed to be horizontally scalable to a very large number
of users. This is facilitated by separate end points for users after
login, the separation of binary and structured data, and a data model
for sharing that does not allow data dependencies between accounts.
1.1. Notational conventions
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described in BCP
14 [RFC2119] [RFC8174] when, and only when, they appear in all
capitals, as shown here.
The underlying format used for this specification is JSON.
Consequently, the terms "object" and "array" as well as the four
primitive types (strings, numbers, booleans, and null) are to be
interpreted as described in section 1 of [RFC8259]. Unless otherwise
noted, all the property names and values are case sensitive.
Some examples in this document contain "partial" JSON documents used
for illustrative purposes. In these examples, three periods "..."
are used to indicate a portion of the document that has been removed
for compactness.
For compatibility with publishing requirements, line breaks have been
inserted inside long JSON strings, with the following continuation
lines indented. To form the valid JSON example, any line breaks
inside a string must be replaced with a space, and any other white-
space after the line break removed.
Unless otherwise specified, examples of API exchanges only show the
_methodCalls_ array of the Request object or the _methodResponses_
array of the Response object. For compactness, the rest of the
Request/Response object is omitted.
Type signatures are given for all JSON values in this document. The
following conventions are used:
o "*" - The type is undefined (the value could be any type, although
permitted values may be constrained by the context of this value).
o "String" - The JSON string type.
Jenkins & Newman Expires September 19, 2019 [Page 4]
Internet-Draft JMAP March 2019
o "Number" - The JSON number type.
o "Boolean" - The JSON boolean type.
o "A[B]" - A JSON object where the keys are all of type "A", and the
values are all of type "B".
o "A[]" - An array of values of type "A".
o "A|B" - The value is either of type "A" or of type "B".
Other types may also be given, with their representation defined
elsewhere in this document.
Object properties may also have a set of attributes defined along
with the type signature. These have the following meanings:
o *server-set*: Only the server can set the value for this property.
The client MUST NOT send this property when creating a new object
of this type.
o *immutable*: The value MUST NOT change after the object is
created.
o *default*: (This is followed by a JSON value). The value that
will be used for this property if it is omitted in an argument, or
when creating a new object of this type.
1.2. The Id data type
All record ids are assigned by the server, and are immutable.
Where "Id" is given as a datatype, it means a "String" of at least 1
and maximum 255 octets in size, and MUST only contain characters from
the "URL and Filename safe" Base 64 Alphabet, as defined in section 5
of [RFC4648], excluding the pad character ("="). This means the
allowed characters are the ASCII alphanumeric characters ("A-Za-
z0-9"), hyphen ("-"), and underscore ("_").
These characters are safe to use in almost any context (e.g.,
filesystems, URIs, IMAP atoms). For maximum safety, servers SHOULD
also follow defensive allocation strategies to avoid creating risks
where glob completion or data type detection may be present (e.g., on
filesystems or in spreadsheets). In particular, it is wise to avoid:
o Ids starting with a dash
o Ids starting with digits
Jenkins & Newman Expires September 19, 2019 [Page 5]
Internet-Draft JMAP March 2019
o Ids that contain only digits
o Ids that differ only by ASCII case (for example, A vs. a)
o the specific sequence of three characters "NIL" (because this
sequence can be confused with the IMAP protocol expression of the
null value)
A good solution to these issues is to prefix every id with a single
alphabetical character.
1.3. The Int and UnsignedInt data types
Where "Int" is given as a data type, it means an integer in the range
-2^53+1 <= value <= 2^53-1, the safe range for integers stored in a
floating-point double, represented as a JSON "Number".
Where "UnsignedInt" is given as a data type, it means an "Int" where
the value MUST be in the range 0 <= value <= 2^53-1.
1.4. The Date and UTCDate data types
Where "Date" is given as a type, it means a string in [RFC3339]
_date-time_ format. To ensure a normalised form, the _time-secfrac_
MUST always be omitted if zero, and any letters in the string (e.g.
"T" and "Z") MUST be upper-case. For example,
""2014-10-30T14:12:00+08:00"".
Where "UTCDate" is given as a type, it means a "Date" where the
_time-offset_ component MUST be "Z" (i.e. it must be in UTC time).
For example, ""2014-10-30T06:12:00Z"".
1.5. JSON as the data encoding format
JSON is a text-based data interchange format as specified in
[RFC8259]. The I-JSON format defined in [RFC7493] is a strict subset
of this, adding restrictions to avoid potentially confusing scenarios
(for example, it mandates that an object MUST NOT have two members
with the same name).
All data sent from the client to the server or from the server to the
client (except binary file upload/download) MUST be valid I-JSON
according to the RFC, and is therefore case-sensitive and encoded in
UTF-8 ([RFC3629]).
Jenkins & Newman Expires September 19, 2019 [Page 6]
Internet-Draft JMAP March 2019
1.6. Terminology
1.6.1. User
A user is a person accessing data via JMAP. A user has a set of
permissions determining the data that they can see.
1.6.2. Accounts
An account is a collection of data. A single account may contain an
arbitrary set of data types, for example a collection of mail,
contacts and calendars. Most JMAP methods take a mandatory
_accountId_ argument that specifies on which account the operations
are to take place.
An account is not the same as a user, although it is common for a
primary account to directly belong to the user. For example, you may
have an account that contains data for a group or business, to which
multiple users have access.
A single set of credentials may provide access to multiple accounts,
for example if another user is sharing their work calendar with the
authenticated user, or if there is a group mailbox for a support-desk
inbox.
In the event of a severe internal error, a server may have to
reallocate ids or do something else that violates standard JMAP data
constraints for an account. In this situation, the data on the
server is no longer compatible with cached data the client may have
from before. The server MUST treat this as though the account has
been deleted and then recreated with a new account id. Clients will
then be forced to throw away any data with the old account id and
refetch all data from scratch.
1.6.3. Data types and records
JMAP provides a uniform interface for creating, retrieving, updating
and deleting various types of objects. A *data type* is a collection
of named, typed properties, just like the schema for a database
table. Each instance of a data type is called a *record*.
The id of a record is immutable, and assigned by the server. The id
MUST be unique among all records of the *same type* within the *same
account*. Ids may clash across accounts, or for two records of
different types within the same account.
Jenkins & Newman Expires September 19, 2019 [Page 7]
Internet-Draft JMAP March 2019
1.7. The JMAP API model
JMAP uses HTTP [RFC7230] to expose API, Push, Upload and Download
resources. All HTTP requests MUST use the "https://" scheme
([RFC2818] HTTP over TLS). All HTTP requests MUST be authenticated.
An authenticated client can fetch the user's JMAP Session object with
details about the data and capabilities the server can provide as
shown in section 2. The client may then exchange data with the
server in the following ways:
1. The client may make an API request to the server to get or set
structured data. This request consists of an ordered series of
method calls. These are processed by the server, which then
returns an ordered series of responses. This is described in
sections 3 to 5.
2. The client may download or upload binary files from/to the
server. This is detailed in section 6.
3. The client may connect to a push channel on the server, to be
notified when data has changed. This is explained in section 7.
1.8. Vendor-specific extensions
Individual services will have custom features they wish to expose
over JMAP. This may take the form of extra data types and/or methods
not in the spec, or extra arguments to JMAP methods, or extra
properties on existing data types (which may also appear in arguments
to methods that take property names).
The server can advertise custom extensions it supports by including
the identifiers in the capabilities object. Identifiers for vendor
extensions MUST be a URL belonging to a domain owned by the vendor,
to avoid conflict. The URL SHOULD resolve to documentation for the
changes the extension makes.
To ensure compatibility with clients that don't know about a specific
custom extension, and for compatibility with future versions of JMAP,
to use an extension the client MUST opt in by passing the appropriate
capability identifier in the _using_ array of the Request object, as
described in section 3.2. The server MUST only follow the
specifications that are opted-into and behave as though it does not
implement anything else when processing a request.
Jenkins & Newman Expires September 19, 2019 [Page 8]
Internet-Draft JMAP March 2019
2. The JMAP Session resource
You need two things to connect to a JMAP server:
1. The URL for the JMAP Session resource. This may be requested
directly from the user, or discovered automatically based on a
username domain (see section 2.2 below).
2. Credentials to authenticate with. How to obtain credentials is
out of scope for this document.
An authenticated GET request to the JMAP Session resource MUST return
the details about the data and capabilities the server can provide to
the client given those credentials.
The response to a successful request is a JSON-encoded *JMAP Session*
object. It has the following properties:
o *capabilities*: "String[Object]" An object specifying the
capabilities of this server. Each key is a URI for a capability
supported by the server. The value for each of these keys is an
object with further information about the server's capabilities in
relation to that capability.
The client MUST ignore any properties it does not understand.
The capabilities object MUST include a property called
"urn:ietf:params:jmap:core". The value of this property is an
object which MUST contain the following information on server
capabilities (suggested minimum values for limits are supplied
that allow clients to make efficient use of the network):
* *maxSizeUpload*: "UnsignedInt" The maximum file size, in
octets, that the server will accept for a single file upload
(for any purpose). Suggested minimum: 50,000,000.
* *maxConcurrentUpload*: "UnsignedInt" The maximum number of
concurrent requests the server will accept to the upload
endpoint. Suggested minimum: 4.
* *maxSizeRequest*: "UnsignedInt" The maximum size, in octets,
that the server will accept for a single request to the API
endpoint. Suggested minimum: 10,000,000.
* *maxConcurrentRequests*: "UnsignedInt" The maximum number of
concurrent requests the server will accept to the API endpoint.
Suggested minimum: 4.
Jenkins & Newman Expires September 19, 2019 [Page 9]
Internet-Draft JMAP March 2019
* *maxCallsInRequest*: "UnsignedInt" The maximum number of method
calls the server will accept in a single request to the API
endpoint. Suggested minimum: 16.
* *maxObjectsInGet*: "UnsignedInt" The maximum number of objects
that the client may request in a single "/get" type method
call. Suggested minimum: 500
* *maxObjectsInSet*: "UnsignedInt" The maximum number of objects
the client may send to create, update or destroy in a single
"/set" type method call. This is the combined total, e.g. if
the maximum is 10 you could not create 7 objects and destroy 6,
as this would be 13 actions, which exceeds the limit.
Suggested minimum: 500.
* *collationAlgorithms*: "String[]" A list of identifiers for
algorithms registered in the collation registry defined in
[RFC4790] that the server supports for sorting when querying
records.
Specifications for future capabilities will define their own
properties on the capabilities object.
Servers MAY advertise vendor-specific JMAP extensions, as
described in section 1.8. To avoid conflict, an identifier for a
vendor-specific extension MUST be a URL with a domain owned by the
vendor. Clients MUST opt in to any capability it wishes to use
(see section 3.2).
o *accounts*: "Id[Account]" A map of *account id* to Account object
for each account (see section 1.5.2) the user has access to. An
*Account* object has the following properties:
* *name*: "String" A user-friendly string to show when presenting
content from this account, e.g. the email address representing
the owner of the account.
* *isPersonal*: "Boolean" This is "true" if the account belongs
to the authenticated user, rather than a group account or a
personal account of another user that has been shared with
them.
* *isReadOnly*: "Boolean" This is "true" if the entire account is
read-only.
* *accountCapabilities*: "String[Object]" The set of capability
URIs for the methods supported in this account. Each key is a
URI for a capability that has methods you can use with this
Jenkins & Newman Expires September 19, 2019 [Page 10]
Internet-Draft JMAP March 2019
account. The value for each of these keys is an object with
further information about the account's permissions and
restrictions with respect to this capability, as defined in the
capability's specification.
The client MUST ignore any properties it does not understand.
The server advertises the full list of capabilities it supports
in the capabilities object, as defined above. If the
capability defines new methods, the server MUST include it in
the _accountCapabilities_ object if the user may use those
methods with this account. It MUST NOT include it in the
_accountCapabilities_ object if the user cannot use those
methods with this account.
For example, you may have access to your own account with mail,
calendars and contacts data, and also a shared account that
only has contacts data (a business address book for example).
In this case the _accountCapabilities_ property on the first
account would include something like
"urn:ietf:params:jmap:mail", "urn:ietf:params:jmap:calendars",
"urn:ietf:params:jmap:contacts", while the second account would
just have the last of these.
Attempts to use the methods defined in a capability with one of
the accounts that does not support that capability are rejected
with an _accountNotSupportedByMethod_ error (see section 3.5.2:
method-level errors).
o *primaryAccounts*: "String[Id]" A map of capability URIs (as found
in _accountCapabilities_) to the account id to be considered the
user's main or default account for data pertaining to that
capability. If no account being returned belongs to the user, or
in any other way there is no appropriate way to determine a
default account, there MAY be no entry for a particular URI, even
though that capability is supported by the server (and in the
capabilities object). "urn:ietf:params:jmap:core" SHOULD NOT be
present.
o *username*: "String" The username associated with the given
credentials, or the empty string if none.
o *apiUrl*: "String" The URL to use for JMAP API requests.
o *downloadUrl*: "String" The URL endpoint to use when downloading
files, in [RFC6570] URI Template (level 1) format. The URL MUST
contain variables called "accountId", "blobId", "type" and "name".
The use of these variables is described in section 6.2. Due to
Jenkins & Newman Expires September 19, 2019 [Page 11]
Internet-Draft JMAP March 2019
potential encoding issues with slashes in content types, it is
RECOMMENDED to put the "type" variable in the query section of the
URL.
o *uploadUrl*: "String" The URL endpoint to use when uploading
files, in [RFC6570] URI Template (level 1) format. The URL MUST
contain a variable called "accountId". The use of this variable
is described in section 6.1.
o *eventSourceUrl*: "String" The URL to connect to for push events,
as described in section 7.3, in [RFC6570] URI Template (level 1)
format. The URL MUST contain variables called "types",
"closeafter" and "ping". The use of these variables is described
in section 7.3.
o *state*: "String" A (preferably short) string representing the
state of this object on the server. If the value of any other
property on the session object changes, this string will change.
The current value is also returned on the API Response object (see
section 3.3), allowing clients to quickly determine if the session
information has changed (e.g. an account has been added or
removed) and so they need to refetch the object.
To ensure future compatibility, other properties MAY be included on
the JMAP Session object. Clients MUST ignore any properties they are
not expecting.
Implementors must take care to avoid inappropriate caching of the
session object at the HTTP layer. Since the client should only
refetch when it detects there is a change (via the sessionState
property of an API response), it is RECOMMENDED to disable HTTP
caching altogether, for example by setting "Cache-Control: no-cache,
no-store, must-revalidate" on the response.
2.1. Example
In the following example JMAP Session object, the user has access to
their own mail and contacts via JMAP, as well as read-only access to
shared mail from another user. The server is advertising a custom
"https://example.com/apis/foobar" capability.
{
"capabilities": {
"urn:ietf:params:jmap:core": {
"maxSizeUpload": 50000000,
"maxConcurrentUpload": 8,
"maxSizeRequest": 10000000,
"maxConcurrentRequest": 8,
Jenkins & Newman Expires September 19, 2019 [Page 12]
Internet-Draft JMAP March 2019
"maxCallsInRequest": 32,
"maxObjectsInGet": 256,
"maxObjectsInSet": 128,
"collationAlgorithms": [
"i;ascii-numeric",
"i;ascii-casemap",
"i;unicode-casemap"
]
},
"urn:ietf:params:jmap:mail": {}
"urn:ietf:params:jmap:contacts": {},
"https://example.com/apis/foobar": {
"maxFoosFinangled": 42
}
},
"accounts": {
"A13824": {
"name": "[email protected]",
"isPersonal": true,
"isReadOnly": false,
"accountCapabilities": {
"urn:ietf:params:jmap:mail": {
"maxMailboxesPerEmail": null,
"maxMailboxDepth": 10,
...
},
"urn:ietf:params:jmap:contacts": {
...
}
}
},
"A97813": {
"name": "[email protected]",
"isPersonal": false,
"isReadOnly": true,
"accountCapabilities": {
"urn:ietf:params:jmap:mail": {
"maxMailboxesPerEmail": 1,
"maxMailboxDepth": 10,
...
}
}
}
},
"primaryAccounts": {
"urn:ietf:params:jmap:mail": "A13824",
"urn:ietf:params:jmap:contacts": "A13824"
},
Jenkins & Newman Expires September 19, 2019 [Page 13]
Internet-Draft JMAP March 2019
"username": "[email protected]",
"apiUrl": "https://jmap.example.com/api/",
"downloadUrl": "https://jmap.example.com
/download/{accountId}/{blobId}/{name}?accept={type}",
"uploadUrl": "https://jmap.example.com/upload/{accountId}/",
"eventSourceUrl": "https://jmap.example.com
/eventsource/?types={types}&closeafter={closeafter}&ping={ping}",
"state": "75128aab4b1b"
}
2.2. Service autodiscovery
There are two standardised autodiscovery methods in use for internet
protocols:
o *DNS SRV* ([RFC2782], [RFC6186] and [RFC6764])
o *.well-known/servicename* ([RFC5785])
A JMAP-supporting host for the domain "example.com" SHOULD publish a
SRV record "_jmap._tcp.example.com" which gives a _hostname_ and
_port_ (usually port "443"). The JMAP Session resource is then
"https://${hostname}[:${port}]/.well-known/jmap" (following any
redirects).
If the client has a username in the form of an email address, it MAY
use the domain portion of this to attempt autodiscovery of the JMAP
server.
3. Structured data exchange
The client may make an API request to the server to get or set
structured data. This request consists of an ordered series of
method calls. These are processed by the server, which then returns
an ordered series of responses.
3.1. Making an API request
To make an API request, the client makes an authenticated POST
request to the API resource, which is defined by the _apiUrl_
property in the JMAP Session object.
The request MUST be of type "application/json" and consist of a
single JSON *Request* object, as defined in section 3.2. If
successful, the response MUST also be of type "application/json" and
consist of a single *Response* object, as defined in section 3.3.
Jenkins & Newman Expires September 19, 2019 [Page 14]
Internet-Draft JMAP March 2019
3.1.1. The Invocation data type
Method calls and responses are represented by the *Invocation* data
type. This is a tuple, represented as a JSON array containing three
elements:
1. A "String" *name* of the method to call or of the response.
2. A "String[*]" object containing _named_ *arguments* for that
method or response.
3. A "String" *method call id*: an arbitrary string from the client
to be echoed back with the responses emitted by that method call
(a method may return 1 or more responses, as it may make implicit
calls to other methods; all responses initiated by this method
call get the same method call id in the response).
3.2. The Request object
A *Request* object has the following properties:
o *using*: "String[]" The set of capabilities the client wishes to
use. The client MAY include capability identifiers even if the
method calls it makes do not utilise those capabilities. The
server advertises the set of specifications it supports in the
JMAP Session object, as keys on the _capabilities_ property.
o *methodCalls*: "Invocation[]" An array of method calls to process
on the server. The method calls MUST be processed sequentially,
in order.
o *createdIds*: "Id[Id]" (optional) A map of (client-specified)
creation id to the id the server assigned when a record was
successfully created.
As described later in this specification, some records may have a
property that contains the id of another record. To allow more
efficient network usage, you can set this property to reference a
record created earlier in the same API request. Since the real id
is unknown when the request is created, the client can instead
specify the creation id it assigned, prefixed with a "#" (see
section 5.3 for more details).
As the server processes API requests, any time it successfully
creates a new record it adds to this map the creation id (see the
_create_ argument to "/set" in section 5.3), with the server-
assigned real id as the value. If it comes across a reference to
Jenkins & Newman Expires September 19, 2019 [Page 15]
Internet-Draft JMAP March 2019
a creation id in a create/update, it looks it up in the map and
replaces the reference with the real id, if found.
The client can pass an initial value for this map as the
_createdIds_ property of the Request. This may be an empty
object. If given in the request, the response will also include a
createdIds property. This allows proxy servers to easily split a
JMAP request into multiple JMAP requests to send to different
servers. For example it could send the first two method calls to
server A, then the third to server B, before sending the fourth to
server A again. By passing the createdIds of the previous
response to the next request, it can ensure all of these still
resolve. See section 5.8 for further discussion of proxy
considerations.
Future specifications MAY add further properties to the Request
object to extend the semantics. To ensure forwards compatibility, a
server MUST ignore any other properties it does not understand on the
JMAP request object.
3.2.1. Example request
{
"using": [ "urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail" ],
"methodCalls": [
[ "method1", {
"arg1": "arg1data",
"arg2": "arg2data"
}, "c1" ],
[ "method2", {
"arg1": "arg1data"
}, "c2" ],
[ "method3", {}, "c3" ]
]
}
3.3. The Response object
A *Response* object has the following properties:
o *methodResponses*: "Invocation[]" An array of responses, in the
same format as the _methodCalls_ on the request object. The
output of the methods MUST be added to the _methodResponses_ array
in the same order as the methods are processed.
o *createdIds*: "Id[Id]" (optional; only returned if given in
request) A map of (client-specified) creation id to the id the
server assigned when a record was successfully created. This MUST
Jenkins & Newman Expires September 19, 2019 [Page 16]
Internet-Draft JMAP March 2019
include all creation ids passed in the original createdIds
parameter of the Request object, as well as any additional ones
added for newly created records.
o *sessionState*: "String" The current value of the "state" string
on the JMAP Session object, as described in section 2. Clients
may use this to detect if this object has changed and needs to be
refetched.
Unless otherwise specified, if the method call completed successfully
its response name is the same as the method name in the request.
3.3.1. Example response:
{
"methodResponses": [
[ "method1", {
"arg1": 3,
"arg2": "foo"
}, "c1" ],
[ "method2", {
"isBlah": true
}, "c2" ],
[ "anotherResponseFromMethod2", {
"data": 10,
"yetmoredata": "Hello"
}, "c2"],
[ "error", {
"type":"unknownMethod"
}, "c3" ]
],
"sessionState": "75128aab4b1b"
}
3.4. Omitting arguments
An argument to a method may be specified to have a default value. If
omitted by the client, the server MUST treat the method call the same
as if the default value had been specified. Similarly, the server
MAY omit any argument in a response which has the default value.
Unless otherwise specified in a method description, "null" is the
default value for any argument in a request or response where this is
allowed by the type signature. Other arguments may only be omitted
if an explicit default value is defined in the method description.
Jenkins & Newman Expires September 19, 2019 [Page 17]
Internet-Draft JMAP March 2019
3.5. Errors
There are three different levels of granularity at which an error may
be returned in JMAP.
When an API request is made, the request as a whole may be rejected
due to rate limiting, malformed JSON, request for an unknown
capability etc. In this case the entire request is rejected with an
appropriate HTTP error response code, and an additional JSON body
with more detail for the client.
Provided the request itself is syntactically valid (the JSON is
valid, and when decoded matches the type signature of a Request
object), the methods within it are executed sequentially by the
server. Each method may individually fail, for example if invalid
arguments are given, or an unknown method name is called.
Finally, methods that make changes to the server state often act upon
a number of different records within a single call. Each record
change may be separately rejected with a SetError, as described in
section 5.3.
3.5.1. Request-level errors
When an HTTP error response is returned to the client, the server
SHOULD return a JSON "problem details" object as the response body,
as per [RFC7807].
The following problem types are defined:
o "urn:ietf:params:jmap:error:unknownCapability" The client included
a capability in the "using" property of the request that the
server does not support.
o "urn:ietf:params:jmap:error:notJSON" The content type of the
request was not "application/json" or the request did not parse as
I-JSON.
o "urn:ietf:params:jmap:error:notRequest" The request parsed as JSON
but did not match the type signature of the Request object.
o "urn:ietf:params:jmap:error:limit" The request was not processed
as it would have exceeded one of the *request* limits defined on
the capability object, such as maxSizeRequest, maxCallsInRequest