me.linkna.linkinbio
Schema Diff
+13 -4
Compatibility Analysis
Breaking Changes Detected
2 breaking changes, 2 non-breaking changes.
Breaking Changes (2)
- KindChanged KindChanged { vertex_id: "me.linkna.linkinbio#widgetMap.latitude", old_kind: "object", new_kind: "string" }
- KindChanged KindChanged { vertex_id: "me.linkna.linkinbio#widgetMap.longitude", old_kind: "object", new_kind: "string" }
Non-Breaking Changes (2)
- AddedVertex AddedVertex { vertex_id: "me.linkna.linkinbio#widgetMap.mapImageRef" }
- AddedEdge AddedEdge { src: "me.linkna.linkinbio#widgetMap", tgt: "me.linkna.linkinbio#widgetMap.mapImageRef", kind: "prop", name: Some("mapImageRef") }
Migration Guidance
Added Elements
AddedVertex { vertex_id: "me.linkna.linkinbio#widgetMap.mapImageRef" }
Additional Notes
- Breaking: KindChanged { vertex_id: "me.linkna.linkinbio#widgetMap.latitude", old_kind: "object", new_kind: "string" }
- Breaking: KindChanged { vertex_id: "me.linkna.linkinbio#widgetMap.longitude", old_kind: "object", new_kind: "string" }
- Non-breaking: AddedEdge { src: "me.linkna.linkinbio#widgetMap", tgt: "me.linkna.linkinbio#widgetMap.mapImageRef", kind: "prop", name: Some("mapImageRef") }
1
1
{
2
2
"$type": "com.atproto.lexicon.schema",
3
3
"defs": {
4
4
"connectedServices": {
5
5
"description": "Saved service credentials/identifiers for pre-filling widget forms.",
6
6
"properties": {
7
7
"githubUsername": {
8
8
"description": "GitHub username.",
9
9
"type": "string"
10
10
},
11
11
"goodreadsUserId": {
12
12
"description": "Goodreads numeric user ID.",
13
13
"type": "string"
14
14
},
15
15
"lastfmUsername": {
16
16
"description": "Last.fm username.",
17
17
"type": "string"
18
18
}
19
19
},
20
20
"type": "object"
21
21
},
22
22
"githubContributionDay": {
23
23
"description": "A single day's contribution data from GitHub.",
24
24
"properties": {
25
25
"count": {
26
26
"description": "Number of contributions on this day.",
27
27
"type": "integer"
28
28
},
29
29
"date": {
30
30
"description": "Date in YYYY-MM-DD format.",
31
31
"type": "string"
32
32
},
33
33
"level": {
34
34
"description": "Contribution intensity level (0=none, 4=highest).",
35
35
"maximum": 4,
36
36
"minimum": 0,
37
37
"type": "integer"
38
38
}
39
39
},
40
40
"required": [
41
41
"date",
42
42
"count",
43
43
"level"
44
44
],
45
45
"type": "object"
46
46
},
47
47
"goodreadsBook": {
48
48
"description": "A book from a Goodreads shelf.",
49
49
"properties": {
50
50
"author": {
51
51
"description": "Book author.",
52
52
"type": "string"
53
53
},
54
54
"coverUrl": {
55
55
"description": "URL to the book cover image.",
56
56
"type": "string"
57
57
},
58
58
"link": {
59
59
"description": "URL to the book on Goodreads.",
60
60
"type": "string"
61
61
},
62
62
"rating": {
63
63
"description": "User's rating (1-5), or absent if unrated.",
64
64
"maximum": 5,
65
65
"minimum": 0,
66
66
"type": "integer"
67
67
},
68
68
"title": {
69
69
"description": "Book title.",
70
70
"type": "string"
71
71
}
72
72
},
73
73
"required": [
74
74
"title",
75
75
"author"
76
76
],
77
77
"type": "object"
78
78
},
79
79
"headerCard": {
80
80
"description": "A section header/divider card.",
81
81
"properties": {
82
82
"alignment": {
83
83
"description": "Text alignment for the header. Defaults to the user's button alignment.",
84
84
"enum": [
85
85
"left",
86
86
"center",
87
87
"right"
88
88
],
89
89
"type": "string"
90
90
},
91
91
"enabled": {
92
92
"description": "Whether the header is visible on the public page. Defaults to true.",
93
93
"type": "boolean"
94
94
},
95
95
"id": {
96
96
"description": "Unique identifier for the card.",
97
97
"type": "string"
98
98
},
99
99
"text": {
100
100
"description": "Header text displayed as a section divider.",
101
101
"maxLength": 100,
102
102
"type": "string"
103
103
},
104
104
"type": {
105
105
"const": "header",
106
106
"description": "Card type discriminator.",
107
107
"type": "string"
108
108
}
109
109
},
110
110
"required": [
111
111
"id",
112
112
"type",
113
113
"text"
114
114
],
115
115
"type": "object"
116
116
},
117
117
"linkCard": {
118
118
"description": "A standard link card.",
119
119
"properties": {
120
120
"enabled": {
121
121
"description": "Whether the card is visible on the public page. Defaults to true.",
122
122
"type": "boolean"
123
123
},
124
124
"highlighted": {
125
125
"description": "Whether the card is visually highlighted.",
126
126
"type": "boolean"
127
127
},
128
128
"id": {
129
129
"description": "Unique identifier for the card.",
130
130
"type": "string"
131
131
},
132
132
"text": {
133
133
"description": "Display text for the card (falls back to URL domain if empty).",
134
134
"maxLength": 100,
135
135
"type": "string"
136
136
},
137
137
"type": {
138
138
"description": "Card type discriminator. Value: 'link' or absent for link cards.",
139
139
"type": "string"
140
140
},
141
141
"url": {
142
142
"description": "URL the card links to.",
143
143
"format": "uri",
144
144
"type": "string"
145
145
}
146
146
},
147
147
"type": "object"
148
148
},
149
149
"main": {
150
150
"description": "A user's link-in-bio page containing cards, theme configuration, and social icons.",
151
151
"key": "literal:self",
152
152
"record": {
153
153
"properties": {
154
154
"cards": {
155
155
"description": "Ordered list of cards on the page.",
156
156
"items": {
157
157
"refs": [
158
158
"#linkCard",
159
159
"#headerCard",
160
160
"#widgetGoodreads",
161
161
"#widgetGithub",
162
162
"#widgetTealfm",
163
163
"#widgetLastfm",
164
164
"#widgetClock",
165
165
"#widgetYoutube",
166
166
"#widgetPatreon",
167
167
"#widgetSubstack",
168
168
"#widgetBeehiiv",
169
169
"#widgetVideo",
170
170
"#widgetTwitch",
171
171
"#widgetDiscord",
172
172
"#widgetReddit",
173
173
"#widgetMedium",
174
174
"#widgetMap"
175
175
],
176
176
"type": "union"
177
177
},
178
178
"type": "array"
179
179
},
180
180
"connectedServices": {
181
181
"ref": "#connectedServices",
182
182
"type": "ref"
183
183
},
184
184
"socialIcons": {
185
185
"description": "Social media icons displayed on the profile.",
186
186
"items": {
187
187
"ref": "#socialIcon",
188
188
"type": "ref"
189
189
},
190
190
"type": "array"
191
191
},
192
192
"theme": {
193
193
"description": "Deprecated: use themeConfig instead.",
194
194
"type": "string"
195
195
},
196
196
"themeConfig": {
197
197
"ref": "#themeConfig",
198
198
"type": "ref"
199
199
}
200
200
},
201
201
"required": [
202
202
"cards"
203
203
],
204
204
"type": "object"
205
205
},
206
206
"type": "record"
207
207
},
208
208
"mediumArticle": {
209
209
"description": "A Medium article.",
210
210
"properties": {
211
211
"claps": {
212
212
"description": "Number of claps.",
213
213
"type": "integer"
214
214
},
215
215
"publishedAt": {
216
216
"description": "When the article was published.",
217
217
"type": "string"
218
218
},
219
219
"readingTime": {
220
220
"description": "Estimated reading time in minutes.",
221
221
"type": "integer"
222
222
},
223
223
"subtitle": {
224
224
"description": "Article subtitle.",
225
225
"type": "string"
226
226
},
227
227
"title": {
228
228
"description": "Article title.",
229
229
"type": "string"
230
230
},
231
231
"url": {
232
232
"description": "Article URL.",
233
233
"type": "string"
234
234
}
235
235
},
236
236
"required": [
237
237
"title",
238
238
"url",
239
239
"publishedAt",
240
240
"claps"
241
241
],
242
242
"type": "object"
243
243
},
244
244
"redditPost": {
245
245
"description": "A Reddit post.",
246
246
"properties": {
247
247
"numComments": {
248
248
"description": "Number of comments.",
249
249
"type": "integer"
250
250
},
251
251
"score": {
252
252
"description": "Post score.",
253
253
"type": "integer"
254
254
},
255
255
"subreddit": {
256
256
"description": "Subreddit name.",
257
257
"type": "string"
258
258
},
259
259
"title": {
260
260
"description": "Post title.",
261
261
"type": "string"
262
262
},
263
263
"url": {
264
264
"description": "Post URL.",
265
265
"type": "string"
266
266
}
267
267
},
268
268
"required": [
269
269
"title",
270
270
"subreddit",
271
271
"url",
272
272
"score",
273
273
"numComments"
274
274
],
275
275
"type": "object"
276
276
},
277
277
"socialIcon": {
278
278
"description": "A social media icon link.",
279
279
"properties": {
280
280
"id": {
281
281
"description": "Unique identifier for the icon.",
282
282
"type": "string"
283
283
},
284
284
"platform": {
285
285
"description": "Platform identifier (e.g., 'bluesky', 'twitter', 'instagram').",
286
286
"type": "string"
287
287
},
288
288
"url": {
289
289
"description": "URL to the user's profile on this platform.",
290
290
"format": "uri",
291
291
"type": "string"
292
292
}
293
293
},
294
294
"required": [
295
295
"id",
296
296
"platform",
297
297
"url"
298
298
],
299
299
"type": "object"
300
300
},
301
301
"tealfmPlay": {
302
302
"description": "A recently played track from teal.fm.",
303
303
"properties": {
304
304
"artistName": {
305
305
"description": "Artist name(s).",
306
306
"type": "string"
307
307
},
308
308
"coverUrl": {
309
309
"description": "URL to the album cover image (from Cover Art Archive).",
310
310
"type": "string"
311
311
},
312
312
"originUrl": {
313
313
"description": "URL to the track on the original music service.",
314
314
"type": "string"
315
315
},
316
316
"playedTime": {
317
317
"description": "When the track was played.",
318
318
"format": "datetime",
319
319
"type": "string"
320
320
},
321
321
"releaseName": {
322
322
"description": "Album/release name.",
323
323
"type": "string"
324
324
},
325
325
"trackName": {
326
326
"description": "Track/song name.",
327
327
"type": "string"
328
328
}
329
329
},
330
330
"required": [
331
331
"trackName",
332
332
"artistName"
333
333
],
334
334
"type": "object"
335
335
},
336
336
"themeConfig": {
337
337
"description": "Theme configuration for the page appearance.",
338
338
"properties": {
339
339
"backgroundColor": {
340
340
"description": "Page background color.",
341
341
"type": "string"
342
342
},
343
343
"backgroundGradient": {
344
344
"description": "CSS gradient for the page background.",
345
345
"type": "string"
346
346
},
347
347
"backgroundImage": {
348
348
"accept": [
349
349
"image/png",
350
350
"image/jpeg",
351
351
"image/webp"
352
352
],
353
353
"description": "Background wallpaper image blob.",
354
354
"maxSize": 10000000,
355
355
"type": "blob"
356
356
},
357
357
"backgroundImageCredit": {
358
358
"description": "Optional credit URL for the wallpaper image artist. Stored for attribution purposes only, not displayed on the public page.",
359
359
"format": "uri",
360
360
"type": "string"
361
361
},
362
362
"buttonAlignment": {
363
363
"description": "Button content alignment. Default: left.",
364
364
"knownValues": [
365
365
"left",
366
366
"right"
367
367
],
368
368
"type": "string"
369
369
},
370
370
"buttonHoverGlow": {
371
371
"description": "Whether buttons glow on hover. Default: false.",
372
372
"type": "boolean"
373
373
},
374
374
"buttonHoverGlowColor": {
375
375
"description": "Color for the button hover glow effect.",
376
376
"type": "string"
377
377
},
378
378
"cardBackgroundColor": {
379
379
"description": "Individual card/button background color.",
380
380
"type": "string"
381
381
},
382
382
"cardBorderColor": {
383
383
"description": "Card/button border color.",
384
384
"type": "string"
385
385
},
386
386
"cardBorderRadius": {
387
387
"description": "Card/button border radius.",
388
388
"knownValues": [
389
389
"none",
390
390
"sm",
391
391
"md",
392
392
"lg",
393
393
"full"
394
394
],
395
395
"type": "string"
396
396
},
397
397
"cardHoverColor": {
398
398
"description": "Card/button border color on hover.",
399
399
"type": "string"
400
400
},
401
401
"cardShadow": {
402
402
"description": "Card/button shadow intensity.",
403
403
"knownValues": [
404
404
"none",
405
405
"sm",
406
406
"md",
407
407
"lg",
408
408
"xl"
409
409
],
410
410
"type": "string"
411
411
},
412
412
"cardTextColor": {
413
413
"description": "Card/button text color.",
414
414
"type": "string"
415
415
},
416
416
"contentCardColor": {
417
417
"description": "Card container background color.",
418
418
"type": "string"
419
419
},
420
420
"cursorSparkles": {
421
421
"description": "Whether cursor has sparkle trail. Default: false.",
422
422
"type": "boolean"
423
423
},
424
424
"cursorStyle": {
425
425
"description": "Custom cursor style. Default: default.",
426
426
"knownValues": [
427
427
"default",
428
428
"hello-kitty"
429
429
],
430
430
"type": "string"
431
431
},
432
432
"fontFamily": {
433
433
"description": "Font family for the page.",
434
434
"type": "string"
435
435
},
436
436
"fontSize": {
437
437
"description": "Font size. Default: md.",
438
438
"knownValues": [
439
439
"sm",
440
440
"md",
441
441
"lg"
442
442
],
443
443
"type": "string"
444
444
},
445
445
"particles": {
446
446
"description": "Background particle effect. Default: none.",
447
447
"knownValues": [
448
448
"none",
449
449
"white",
450
450
"blue",
451
451
"leaves",
452
452
"grid-sm",
453
453
"grid-lg"
454
454
],
455
455
"type": "string"
456
456
},
457
457
"preset": {
458
458
"description": "Theme preset ID (e.g., 'custom', 'agate', 'air', 'astrid', 'aura').",
459
459
"type": "string"
460
460
},
461
461
"profileAlignment": {
462
462
"description": "Profile section alignment. Default: center.",
463
463
"knownValues": [
464
464
"left",
465
465
"center",
466
466
"right"
467
467
],
468
468
"type": "string"
469
469
},
470
470
"profilePictureShape": {
471
471
"description": "Profile picture shape. Default: circle.",
472
472
"knownValues": [
473
473
"circle",
474
474
"rounded",
475
475
"square"
476
476
],
477
477
"type": "string"
478
478
},
479
479
"profilePictureSize": {
480
480
"description": "Profile picture size. Default: sm.",
481
481
"knownValues": [
482
482
"sm",
483
483
"md",
484
484
"lg"
485
485
],
486
486
"type": "string"
487
487
},
488
488
"profileTextColor": {
489
489
"description": "Profile section text color.",
490
490
"type": "string"
491
491
},
492
492
"showBranding": {
493
493
"description": "Whether Linkname branding is visible. Default: true.",
494
494
"type": "boolean"
495
495
},
496
496
"socialIconsBorderColor": {
497
497
"description": "Border color for social icons dock/sphere.",
498
498
"type": "string"
499
499
},
500
500
"socialIconsColor": {
501
501
"description": "Social icons color.",
502
502
"type": "string"
503
503
},
504
504
"socialIconsShape": {
505
505
"description": "Social icons container shape. Default: dock.",
506
506
"knownValues": [
507
507
"dock",
508
508
"sphere"
509
509
],
510
510
"type": "string"
511
511
},
512
512
"socialIconsShapeColor": {
513
513
"description": "Background color for social icons dock/sphere.",
514
514
"type": "string"
515
515
}
516
516
},
517
517
"type": "object"
518
518
},
519
519
"videoAspectRatio": {
520
520
"description": "Video aspect ratio dimensions.",
521
521
"properties": {
522
522
"height": {
523
523
"description": "Video height.",
524
524
"type": "integer"
525
525
},
526
526
"width": {
527
527
"description": "Video width.",
528
528
"type": "integer"
529
529
}
530
530
},
531
531
"required": [
532
532
"width",
533
533
"height"
534
534
],
535
535
"type": "object"
536
536
},
537
537
"widgetBeehiiv": {
538
538
"description": "A Beehiiv publication widget card.",
539
539
"properties": {
540
540
"description": {
541
541
"description": "Publication description.",
542
542
"type": "string"
543
543
},
544
544
"enabled": {
545
545
"description": "Whether the widget is visible on the public page. Defaults to true.",
546
546
"type": "boolean"
547
547
},
548
548
"id": {
549
549
"description": "Unique identifier for the card.",
550
550
"type": "string"
551
551
},
552
552
"imageUrl": {
553
553
"description": "Publication image URL.",
554
554
"type": "string"
555
555
},
556
556
"lastSyncedAt": {
557
557
"description": "When the publication data was last fetched.",
558
558
"format": "datetime",
559
559
"type": "string"
560
560
},
561
561
"publicationId": {
562
562
"description": "Beehiiv publication ID.",
563
563
"type": "string"
564
564
},
565
565
"publicationName": {
566
566
"description": "Beehiiv publication name.",
567
567
"type": "string"
568
568
},
569
569
"publicationUrl": {
570
570
"description": "URL to the Beehiiv publication.",
571
571
"type": "string"
572
572
},
573
573
"size": {
574
574
"description": "Widget display size. Default: 1x1.",
575
575
"knownValues": [
576
576
"1x1",
577
577
"1x2",
578
578
"2x2",
579
579
"2x1"
580
580
],
581
581
"type": "string"
582
582
},
583
583
"type": {
584
584
"const": "beehiiv",
585
585
"description": "Card type discriminator.",
586
586
"type": "string"
587
587
}
588
588
},
589
589
"required": [
590
590
"id",
591
591
"type",
592
592
"publicationId",
593
593
"publicationName",
594
594
"publicationUrl"
595
595
],
596
596
"type": "object"
597
597
},
598
598
"widgetClock": {
599
599
"description": "A clock, countdown, or stopwatch timer widget card.",
600
600
"properties": {
601
601
"enabled": {
602
602
"description": "Whether the widget is visible on the public page. Defaults to true.",
603
603
"type": "boolean"
604
604
},
605
605
"id": {
606
606
"description": "Unique identifier for the card.",
607
607
"type": "string"
608
608
},
609
609
"label": {
610
610
"description": "Optional display label for the widget.",
611
611
"maxLength": 100,
612
612
"type": "string"
613
613
},
614
614
"mode": {
615
615
"description": "Widget mode: clock (timezone display), countdown (to a target date), or timer (interactive stopwatch).",
616
616
"knownValues": [
617
617
"clock",
618
618
"countdown",
619
619
"timer"
620
620
],
621
621
"type": "string"
622
622
},
623
623
"size": {
624
624
"description": "Widget display size. Default: 1x1.",
625
625
"knownValues": [
626
626
"1x1",
627
627
"1x2",
628
628
"2x2",
629
629
"2x1"
630
630
],
631
631
"type": "string"
632
632
},
633
633
"targetDate": {
634
634
"description": "ISO 8601 target date for countdown mode.",
635
635
"format": "datetime",
636
636
"type": "string"
637
637
},
638
638
"timezone": {
639
639
"description": "IANA timezone identifier for clock mode (e.g. 'America/New_York').",
640
640
"type": "string"
641
641
},
642
642
"type": {
643
643
"const": "clock",
644
644
"description": "Card type discriminator.",
645
645
"type": "string"
646
646
}
647
647
},
648
648
"required": [
649
649
"id",
650
650
"type",
651
651
"mode"
652
652
],
653
653
"type": "object"
654
654
},
655
655
"widgetDiscord": {
656
656
"description": "A Discord server widget card.",
657
657
"properties": {
658
658
"bannerUrl": {
659
659
"description": "Server banner URL.",
660
660
"type": "string"
661
661
},
662
662
"description": {
663
663
"description": "Server description.",
664
664
"type": "string"
665
665
},
666
666
"enabled": {
667
667
"description": "Whether the widget is visible on the public page. Defaults to true.",
668
668
"type": "boolean"
669
669
},
670
670
"iconUrl": {
671
671
"description": "Server icon URL.",
672
672
"type": "string"
673
673
},
674
674
"id": {
675
675
"description": "Unique identifier for the card.",
676
676
"type": "string"
677
677
},
678
678
"inviteUrl": {
679
679
"description": "Discord invite URL.",
680
680
"type": "string"
681
681
},
682
682
"lastSyncedAt": {
683
683
"description": "When the server data was last fetched.",
684
684
"format": "datetime",
685
685
"type": "string"
686
686
},
687
687
"memberCount": {
688
688
"description": "Total member count.",
689
689
"type": "integer"
690
690
},
691
691
"presenceCount": {
692
692
"description": "Online member count.",
693
693
"type": "integer"
694
694
},
695
695
"serverId": {
696
696
"description": "Discord server ID.",
697
697
"type": "string"
698
698
},
699
699
"serverName": {
700
700
"description": "Discord server name.",
701
701
"type": "string"
702
702
},
703
703
"size": {
704
704
"description": "Widget display size. Default: 1x1.",
705
705
"knownValues": [
706
706
"1x1",
707
707
"1x2",
708
708
"2x2",
709
709
"2x1"
710
710
],
711
711
"type": "string"
712
712
},
713
713
"type": {
714
714
"const": "discord",
715
715
"description": "Card type discriminator.",
716
716
"type": "string"
717
717
}
718
718
},
719
719
"required": [
720
720
"id",
721
721
"type",
722
722
"serverId",
723
723
"serverName",
724
724
"inviteUrl"
725
725
],
726
726
"type": "object"
727
727
},
728
728
"widgetGithub": {
729
729
"description": "A GitHub contributions graph widget card.",
730
730
"properties": {
731
731
"contributions": {
732
732
"description": "Contribution data for the last year.",
733
733
"items": {
734
734
"ref": "#githubContributionDay",
735
735
"type": "ref"
736
736
},
737
737
"type": "array"
738
738
},
739
739
"enabled": {
740
740
"description": "Whether the widget is visible on the public page. Defaults to true.",
741
741
"type": "boolean"
742
742
},
743
743
"githubUsername": {
744
744
"description": "GitHub username.",
745
745
"type": "string"
746
746
},
747
747
"id": {
748
748
"description": "Unique identifier for the card.",
749
749
"type": "string"
750
750
},
751
751
"lastSyncedAt": {
752
752
"description": "When the contribution data was last fetched from GitHub.",
753
753
"format": "datetime",
754
754
"type": "string"
755
755
},
756
756
"size": {
757
757
"description": "Widget display size. Default: 1x1.",
758
758
"knownValues": [
759
759
"1x1",
760
760
"1x2",
761
761
"2x2"
762
762
],
763
763
"type": "string"
764
764
},
765
765
"totalContributions": {
766
766
"description": "Total number of contributions in the last year.",
767
767
"type": "integer"
768
768
},
769
769
"type": {
770
770
"const": "github",
771
771
"description": "Card type discriminator.",
772
772
"type": "string"
773
773
}
774
774
},
775
775
"required": [
776
776
"id",
777
777
"type",
778
778
"githubUsername",
779
779
"contributions"
780
780
],
781
781
"type": "object"
782
782
},
783
783
"widgetGoodreads": {
784
784
"description": "A Goodreads bookshelf widget card.",
785
785
"properties": {
786
786
"books": {
787
787
"description": "Books on the currently-reading shelf.",
788
788
"items": {
789
789
"ref": "#goodreadsBook",
790
790
"type": "ref"
791
791
},
792
792
"type": "array"
793
793
},
794
794
"enabled": {
795
795
"description": "Whether the widget is visible on the public page. Defaults to true.",
796
796
"type": "boolean"
797
797
},
798
798
"goodreadsUserId": {
799
799
"description": "Goodreads numeric user ID.",
800
800
"type": "string"
801
801
},
802
802
"id": {
803
803
"description": "Unique identifier for the card.",
804
804
"type": "string"
805
805
},
806
806
"lastSyncedAt": {
807
807
"description": "When the book data was last fetched from Goodreads.",
808
808
"format": "datetime",
809
809
"type": "string"
810
810
},
811
811
"readBooks": {
812
812
"description": "Books on the read shelf (used by 1x2 size).",
813
813
"items": {
814
814
"ref": "#goodreadsBook",
815
815
"type": "ref"
816
816
},
817
817
"type": "array"
818
818
},
819
819
"shelf": {
820
820
"description": "Shelf name (currently-reading, read, or to-read).",
821
821
"type": "string"
822
822
},
823
823
"size": {
824
824
"description": "Widget display size. Default: 1x1.",
825
825
"knownValues": [
826
826
"1x1",
827
827
"1x2",
828
828
"2x2"
829
829
],
830
830
"type": "string"
831
831
},
832
832
"type": {
833
833
"const": "goodreads",
834
834
"description": "Card type discriminator.",
835
835
"type": "string"
836
836
}
837
837
},
838
838
"required": [
839
839
"id",
840
840
"type",
841
841
"goodreadsUserId",
842
842
"shelf",
843
843
"books"
844
844
],
845
845
"type": "object"
846
846
},
847
847
"widgetLastfm": {
848
848
"description": "A Last.fm recently played tracks widget card.",
849
849
"properties": {
850
850
"coverArtNotice": {
851
851
"description": "Copyright notice for cover art images.",
852
852
"type": "string"
853
853
},
854
854
"enabled": {
855
855
"description": "Whether the widget is visible on the public page. Defaults to true.",
856
856
"type": "boolean"
857
857
},
858
858
"id": {
859
859
"description": "Unique identifier for the card.",
860
860
"type": "string"
861
861
},
862
862
"lastSyncedAt": {
863
863
"description": "When the play data was last fetched from Last.fm.",
864
864
"format": "datetime",
865
865
"type": "string"
866
866
},
867
867
"lastfmUsername": {
868
868
"description": "Last.fm username for fetching scrobbles.",
869
869
"type": "string"
870
870
},
871
871
"plays": {
872
872
"description": "Recently played tracks from Last.fm.",
873
873
"items": {
874
874
"ref": "#tealfmPlay",
875
875
"type": "ref"
876
876
},
877
877
"type": "array"
878
878
},
879
879
"size": {
880
880
"description": "Widget display size. Default: 1x1.",
881
881
"knownValues": [
882
882
"1x1",
883
883
"1x2",
884
884
"2x2"
885
885
],
886
886
"type": "string"
887
887
},
888
888
"type": {
889
889
"const": "lastfm",
890
890
"description": "Card type discriminator.",
891
891
"type": "string"
892
892
}
893
893
},
894
894
"required": [
895
895
"id",
896
896
"type",
897
897
"lastfmUsername",
898
898
"plays"
899
899
],
900
900
"type": "object"
901
901
},
902
902
"widgetMap": {
903
903
"description": "A map location widget card.",
904
904
"properties": {
905
905
"enabled": {
906
906
"description": "Whether the widget is visible on the public page. Defaults to true.",
907
907
"type": "boolean"
908
908
},
909
909
"id": {
910
910
"description": "Unique identifier for the card.",
911
911
"type": "string"
912
912
},
913
913
"latitude": {
914
-
"description": "Latitude coordinate.",
915
-
"type": "number"
914
+
"description": "Latitude coordinate as string (AT Protocol does not support floats).",
915
+
"type": "string"
916
916
},
917
917
"locationName": {
918
918
"description": "Display name for the location.",
919
919
"type": "string"
920
920
},
921
921
"longitude": {
922
-
"description": "Longitude coordinate.",
923
-
"type": "number"
922
+
"description": "Longitude coordinate as string (AT Protocol does not support floats).",
923
+
"type": "string"
924
+
},
925
+
"mapImageRef": {
926
+
"accept": [
927
+
"image/png",
928
+
"image/jpeg"
929
+
],
930
+
"description": "Cached static map image blob to avoid repeated Stadia Maps API calls.",
931
+
"maxSize": 5000000,
932
+
"type": "blob"
924
933
},
925
934
"size": {
926
935
"description": "Widget display size. Default: 1x1.",
927
936
"knownValues": [
928
937
"1x1",
929
938
"1x2",
930
939
"2x2",
931
940
"2x1"
932
941
],
933
942
"type": "string"
934
943
},
935
944
"style": {
936
945
"description": "Map style. Default: light.",
937
946
"knownValues": [
938
947
"light",
939
948
"dark"
940
949
],
941
950
"type": "string"
942
951
},
943
952
"type": {
944
953
"const": "map",
945
954
"description": "Card type discriminator.",
946
955
"type": "string"
947
956
},
948
957
"zoom": {
949
958
"description": "Map zoom level (1-18). Default: 12.",
950
959
"type": "integer"
951
960
}
952
961
},
953
962
"required": [
954
963
"id",
955
964
"type",
956
965
"locationName",
957
966
"latitude",
958
967
"longitude"
959
968
],
960
969
"type": "object"
961
970
},
962
971
"widgetMedium": {
963
972
"description": "A Medium profile widget card.",
964
973
"properties": {
965
974
"articles": {
966
975
"description": "Recent articles.",
967
976
"items": {
968
977
"ref": "#mediumArticle",
969
978
"type": "ref"
970
979
},
971
980
"type": "array"
972
981
},
973
982
"bio": {
974
983
"description": "Medium bio.",
975
984
"type": "string"
976
985
},
977
986
"displayName": {
978
987
"description": "Medium display name.",
979
988
"type": "string"
980
989
},
981
990
"enabled": {
982
991
"description": "Whether the widget is visible on the public page. Defaults to true.",
983
992
"type": "boolean"
984
993
},
985
994
"followerCount": {
986
995
"description": "Number of followers.",
987
996
"type": "integer"
988
997
},
989
998
"id": {
990
999
"description": "Unique identifier for the card.",
991
1000
"type": "string"
992
1001
},
993
1002
"lastSyncedAt": {
994
1003
"description": "When the Medium data was last fetched.",
995
1004
"format": "datetime",
996
1005
"type": "string"
997
1006
},
998
1007
"profileUrl": {
999
1008
"description": "Medium profile URL.",
1000
1009
"type": "string"
1001
1010
},
1002
1011
"size": {
1003
1012
"description": "Widget display size. Default: 1x1.",
1004
1013
"knownValues": [
1005
1014
"1x1",
1006
1015
"1x2",
1007
1016
"2x2",
1008
1017
"2x1"
1009
1018
],
1010
1019
"type": "string"
1011
1020
},
1012
1021
"type": {
1013
1022
"const": "medium",
1014
1023
"description": "Card type discriminator.",
1015
1024
"type": "string"
1016
1025
},
1017
1026
"username": {
1018
1027
"description": "Medium username.",
1019
1028
"type": "string"
1020
1029
}
1021
1030
},
1022
1031
"required": [
1023
1032
"id",
1024
1033
"type",
1025
1034
"username",
1026
1035
"profileUrl"
1027
1036
],
1028
1037
"type": "object"
1029
1038
},
1030
1039
"widgetPatreon": {
1031
1040
"description": "A Patreon campaign widget card.",
1032
1041
"properties": {
1033
1042
"campaignId": {
1034
1043
"description": "Patreon campaign ID.",
1035
1044
"type": "string"
1036
1045
},
1037
1046
"campaignUrl": {
1038
1047
"description": "URL to the Patreon campaign.",
1039
1048
"type": "string"
1040
1049
},
1041
1050
"creationName": {
1042
1051
"description": "Name of the creation/project.",
1043
1052
"type": "string"
1044
1053
},
1045
1054
"creatorName": {
1046
1055
"description": "Patreon creator name.",
1047
1056
"type": "string"
1048
1057
},
1049
1058
"enabled": {
1050
1059
"description": "Whether the widget is visible on the public page. Defaults to true.",
1051
1060
"type": "boolean"
1052
1061
},
1053
1062
"id": {
1054
1063
"description": "Unique identifier for the card.",
1055
1064
"type": "string"
1056
1065
},
1057
1066
"imageUrl": {
1058
1067
"description": "Campaign image URL.",
1059
1068
"type": "string"
1060
1069
},
1061
1070
"lastSyncedAt": {
1062
1071
"description": "When the campaign data was last fetched.",
1063
1072
"format": "datetime",
1064
1073
"type": "string"
1065
1074
},
1066
1075
"patronCount": {
1067
1076
"description": "Number of patrons.",
1068
1077
"type": "integer"
1069
1078
},
1070
1079
"postCount": {
1071
1080
"description": "Number of posts.",
1072
1081
"type": "integer"
1073
1082
},
1074
1083
"size": {
1075
1084
"description": "Widget display size. Default: 1x1.",
1076
1085
"knownValues": [
1077
1086
"1x1",
1078
1087
"1x2",
1079
1088
"2x2",
1080
1089
"2x1"
1081
1090
],
1082
1091
"type": "string"
1083
1092
},
1084
1093
"type": {
1085
1094
"const": "patreon",
1086
1095
"description": "Card type discriminator.",
1087
1096
"type": "string"
1088
1097
}
1089
1098
},
1090
1099
"required": [
1091
1100
"id",
1092
1101
"type",
1093
1102
"campaignId",
1094
1103
"creatorName",
1095
1104
"campaignUrl"
1096
1105
],
1097
1106
"type": "object"
1098
1107
},
1099
1108
"widgetReddit": {
1100
1109
"description": "A Reddit profile widget card.",
1101
1110
"properties": {
1102
1111
"avatarUrl": {
1103
1112
"description": "Reddit avatar URL.",
1104
1113
"type": "string"
1105
1114
},
1106
1115
"commentKarma": {
1107
1116
"description": "Comment karma.",
1108
1117
"type": "integer"
1109
1118
},
1110
1119
"enabled": {
1111
1120
"description": "Whether the widget is visible on the public page. Defaults to true.",
1112
1121
"type": "boolean"
1113
1122
},
1114
1123
"id": {
1115
1124
"description": "Unique identifier for the card.",
1116
1125
"type": "string"
1117
1126
},
1118
1127
"karma": {
1119
1128
"description": "Total karma.",
1120
1129
"type": "integer"
1121
1130
},
1122
1131
"lastSyncedAt": {
1123
1132
"description": "When the Reddit data was last fetched.",
1124
1133
"format": "datetime",
1125
1134
"type": "string"
1126
1135
},
1127
1136
"linkKarma": {
1128
1137
"description": "Link karma.",
1129
1138
"type": "integer"
1130
1139
},
1131
1140
"profileUrl": {
1132
1141
"description": "Reddit profile URL.",
1133
1142
"type": "string"
1134
1143
},
1135
1144
"recentPosts": {
1136
1145
"description": "Recent posts.",
1137
1146
"items": {
1138
1147
"ref": "#redditPost",
1139
1148
"type": "ref"
1140
1149
},
1141
1150
"type": "array"
1142
1151
},
1143
1152
"size": {
1144
1153
"description": "Widget display size. Default: 1x1.",
1145
1154
"knownValues": [
1146
1155
"1x1",
1147
1156
"1x2",
1148
1157
"2x2",
1149
1158
"2x1"
1150
1159
],
1151
1160
"type": "string"
1152
1161
},
1153
1162
"type": {
1154
1163
"const": "reddit",
1155
1164
"description": "Card type discriminator.",
1156
1165
"type": "string"
1157
1166
},
1158
1167
"username": {
1159
1168
"description": "Reddit username.",
1160
1169
"type": "string"
1161
1170
}
1162
1171
},
1163
1172
"required": [
1164
1173
"id",
1165
1174
"type",
1166
1175
"username",
1167
1176
"profileUrl"
1168
1177
],
1169
1178
"type": "object"
1170
1179
},
1171
1180
"widgetSubstack": {
1172
1181
"description": "A Substack publication widget card.",
1173
1182
"properties": {
1174
1183
"authorName": {
1175
1184
"description": "Author name.",
1176
1185
"type": "string"
1177
1186
},
1178
1187
"coverImageUrl": {
1179
1188
"description": "Publication cover image URL.",
1180
1189
"type": "string"
1181
1190
},
1182
1191
"description": {
1183
1192
"description": "Publication description.",
1184
1193
"type": "string"
1185
1194
},
1186
1195
"enabled": {
1187
1196
"description": "Whether the widget is visible on the public page. Defaults to true.",
1188
1197
"type": "boolean"
1189
1198
},
1190
1199
"id": {
1191
1200
"description": "Unique identifier for the card.",
1192
1201
"type": "string"
1193
1202
},
1194
1203
"imageUrl": {
1195
1204
"description": "Publication image URL.",
1196
1205
"type": "string"
1197
1206
},
1198
1207
"lastSyncedAt": {
1199
1208
"description": "When the publication data was last fetched.",
1200
1209
"format": "datetime",
1201
1210
"type": "string"
1202
1211
},
1203
1212
"postCount": {
1204
1213
"description": "Number of posts.",
1205
1214
"type": "integer"
1206
1215
},
1207
1216
"publicationId": {
1208
1217
"description": "Substack publication ID.",
1209
1218
"type": "string"
1210
1219
},
1211
1220
"publicationName": {
1212
1221
"description": "Substack publication name.",
1213
1222
"type": "string"
1214
1223
},
1215
1224
"publicationUrl": {
1216
1225
"description": "URL to the Substack publication.",
1217
1226
"type": "string"
1218
1227
},
1219
1228
"size": {
1220
1229
"description": "Widget display size. Default: 1x1.",
1221
1230
"knownValues": [
1222
1231
"1x1",
1223
1232
"1x2",
1224
1233
"2x2",
1225
1234
"2x1"
1226
1235
],
1227
1236
"type": "string"
1228
1237
},
1229
1238
"subscriberCount": {
1230
1239
"description": "Number of subscribers.",
1231
1240
"type": "integer"
1232
1241
},
1233
1242
"type": {
1234
1243
"const": "substack",
1235
1244
"description": "Card type discriminator.",
1236
1245
"type": "string"
1237
1246
}
1238
1247
},
1239
1248
"required": [
1240
1249
"id",
1241
1250
"type",
1242
1251
"publicationId",
1243
1252
"publicationName",
1244
1253
"publicationUrl"
1245
1254
],
1246
1255
"type": "object"
1247
1256
},
1248
1257
"widgetTealfm": {
1249
1258
"description": "A teal.fm recently played tracks widget card.",
1250
1259
"properties": {
1251
1260
"coverArtNotice": {
1252
1261
"description": "Copyright notice for cover art images.",
1253
1262
"type": "string"
1254
1263
},
1255
1264
"enabled": {
1256
1265
"description": "Whether the widget is visible on the public page. Defaults to true.",
1257
1266
"type": "boolean"
1258
1267
},
1259
1268
"id": {
1260
1269
"description": "Unique identifier for the card.",
1261
1270
"type": "string"
1262
1271
},
1263
1272
"lastSyncedAt": {
1264
1273
"description": "When the play data was last fetched from the PDS.",
1265
1274
"format": "datetime",
1266
1275
"type": "string"
1267
1276
},
1268
1277
"plays": {
1269
1278
"description": "Recently played tracks.",
1270
1279
"items": {
1271
1280
"ref": "#tealfmPlay",
1272
1281
"type": "ref"
1273
1282
},
1274
1283
"type": "array"
1275
1284
},
1276
1285
"size": {
1277
1286
"description": "Widget display size. Default: 1x1.",
1278
1287
"knownValues": [
1279
1288
"1x1",
1280
1289
"1x2",
1281
1290
"2x2"
1282
1291
],
1283
1292
"type": "string"
1284
1293
},
1285
1294
"source": {
1286
1295
"description": "Data source for the widget. 'lastfm' for imported Last.fm scrobbles, 'tealfm' (default) for native AT Protocol plays.",
1287
1296
"knownValues": [
1288
1297
"tealfm",
1289
1298
"lastfm"
1290
1299
],
1291
1300
"type": "string"
1292
1301
},
1293
1302
"type": {
1294
1303
"const": "tealfm",
1295
1304
"description": "Card type discriminator.",
1296
1305
"type": "string"
1297
1306
}
1298
1307
},
1299
1308
"required": [
1300
1309
"id",
1301
1310
"type",
1302
1311
"plays"
1303
1312
],
1304
1313
"type": "object"
1305
1314
},
1306
1315
"widgetTwitch": {
1307
1316
"description": "A Twitch channel widget card.",
1308
1317
"properties": {
1309
1318
"displayName": {
1310
1319
"description": "Twitch display name.",
1311
1320
"type": "string"
1312
1321
},
1313
1322
"enabled": {
1314
1323
"description": "Whether the widget is visible on the public page. Defaults to true.",
1315
1324
"type": "boolean"
1316
1325
},
1317
1326
"id": {
1318
1327
"description": "Unique identifier for the card.",
1319
1328
"type": "string"
1320
1329
},
1321
1330
"isLive": {
1322
1331
"description": "Whether the channel is currently live.",
1323
1332
"type": "boolean"
1324
1333
},
1325
1334
"lastSyncedAt": {
1326
1335
"description": "When the channel data was last fetched.",
1327
1336
"format": "datetime",
1328
1337
"type": "string"
1329
1338
},
1330
1339
"profileImageUrl": {
1331
1340
"description": "Twitch profile image URL.",
1332
1341
"type": "string"
1333
1342
},
1334
1343
"size": {
1335
1344
"description": "Widget display size. Default: 1x1.",
1336
1345
"knownValues": [
1337
1346
"1x1",
1338
1347
"1x2",
1339
1348
"2x2",
1340
1349
"2x1"
1341
1350
],
1342
1351
"type": "string"
1343
1352
},
1344
1353
"streamGame": {
1345
1354
"description": "Current stream game/category.",
1346
1355
"type": "string"
1347
1356
},
1348
1357
"streamTitle": {
1349
1358
"description": "Current stream title.",
1350
1359
"type": "string"
1351
1360
},
1352
1361
"type": {
1353
1362
"const": "twitch",
1354
1363
"description": "Card type discriminator.",
1355
1364
"type": "string"
1356
1365
},
1357
1366
"username": {
1358
1367
"description": "Twitch username.",
1359
1368
"type": "string"
1360
1369
},
1361
1370
"viewerCount": {
1362
1371
"description": "Current viewer count.",
1363
1372
"type": "integer"
1364
1373
}
1365
1374
},
1366
1375
"required": [
1367
1376
"id",
1368
1377
"type",
1369
1378
"username"
1370
1379
],
1371
1380
"type": "object"
1372
1381
},
1373
1382
"widgetVideo": {
1374
1383
"description": "A video widget card.",
1375
1384
"properties": {
1376
1385
"alt": {
1377
1386
"description": "Alt text for accessibility.",
1378
1387
"maxLength": 1000,
1379
1388
"type": "string"
1380
1389
},
1381
1390
"aspectRatio": {
1382
1391
"description": "Video aspect ratio.",
1383
1392
"ref": "#videoAspectRatio",
1384
1393
"type": "ref"
1385
1394
},
1386
1395
"createdAt": {
1387
1396
"description": "When the video was uploaded.",
1388
1397
"format": "datetime",
1389
1398
"type": "string"
1390
1399
},
1391
1400
"did": {
1392
1401
"description": "Author DID for constructing PDS blob URLs.",
1393
1402
"type": "string"
1394
1403
},
1395
1404
"enabled": {
1396
1405
"description": "Whether the widget is visible on the public page. Defaults to true.",
1397
1406
"type": "boolean"
1398
1407
},
1399
1408
"id": {
1400
1409
"description": "Unique identifier for the card.",
1401
1410
"type": "string"
1402
1411
},
1403
1412
"loop": {
1404
1413
"description": "Whether the video loops. Defaults to true.",
1405
1414
"type": "boolean"
1406
1415
},
1407
1416
"muted": {
1408
1417
"description": "Whether the video is muted. Defaults to true.",
1409
1418
"type": "boolean"
1410
1419
},
1411
1420
"showOverlay": {
1412
1421
"description": "Whether to show the title overlay. Defaults to false.",
1413
1422
"type": "boolean"
1414
1423
},
1415
1424
"size": {
1416
1425
"description": "Widget display size. Default: 1x1.",
1417
1426
"knownValues": [
1418
1427
"1x1",
1419
1428
"1x2",
1420
1429
"2x2",
1421
1430
"2x1"
1422
1431
],
1423
1432
"type": "string"
1424
1433
},
1425
1434
"title": {
1426
1435
"description": "Video title overlay.",
1427
1436
"maxLength": 100,
1428
1437
"type": "string"
1429
1438
},
1430
1439
"type": {
1431
1440
"const": "video",
1432
1441
"description": "Card type discriminator.",
1433
1442
"type": "string"
1434
1443
},
1435
1444
"videoBlobRef": {
1436
1445
"description": "Reference to the uploaded video blob.",
1437
1446
"type": "blob"
1438
1447
}
1439
1448
},
1440
1449
"required": [
1441
1450
"id",
1442
1451
"type",
1443
1452
"videoBlobRef",
1444
1453
"did"
1445
1454
],
1446
1455
"type": "object"
1447
1456
},
1448
1457
"widgetYoutube": {
1449
1458
"description": "A YouTube channel widget card.",
1450
1459
"properties": {
1451
1460
"channelId": {
1452
1461
"description": "YouTube channel ID.",
1453
1462
"type": "string"
1454
1463
},
1455
1464
"channelName": {
1456
1465
"description": "YouTube channel name.",
1457
1466
"type": "string"
1458
1467
},
1459
1468
"channelUrl": {
1460
1469
"description": "URL to the YouTube channel.",
1461
1470
"type": "string"
1462
1471
},
1463
1472
"enabled": {
1464
1473
"description": "Whether the widget is visible on the public page. Defaults to true.",
1465
1474
"type": "boolean"
1466
1475
},
1467
1476
"id": {
1468
1477
"description": "Unique identifier for the card.",
1469
1478
"type": "string"
1470
1479
},
1471
1480
"lastSyncedAt": {
1472
1481
"description": "When the video data was last fetched.",
1473
1482
"format": "datetime",
1474
1483
"type": "string"
1475
1484
},
1476
1485
"latestVideo": {
1477
1486
"description": "The latest video from the channel.",
1478
1487
"ref": "#youtubeVideo",
1479
1488
"type": "ref"
1480
1489
},
1481
1490
"size": {
1482
1491
"description": "Widget display size. Default: 1x1.",
1483
1492
"knownValues": [
1484
1493
"1x1",
1485
1494
"1x2",
1486
1495
"2x2",
1487
1496
"2x1"
1488
1497
],
1489
1498
"type": "string"
1490
1499
},
1491
1500
"type": {
1492
1501
"const": "youtube",
1493
1502
"description": "Card type discriminator.",
1494
1503
"type": "string"
1495
1504
}
1496
1505
},
1497
1506
"required": [
1498
1507
"id",
1499
1508
"type",
1500
1509
"channelId",
1501
1510
"channelName",
1502
1511
"channelUrl"
1503
1512
],
1504
1513
"type": "object"
1505
1514
},
1506
1515
"youtubeVideo": {
1507
1516
"description": "A YouTube video.",
1508
1517
"properties": {
1509
1518
"isShort": {
1510
1519
"description": "Whether this is a YouTube Short.",
1511
1520
"type": "boolean"
1512
1521
},
1513
1522
"publishedAt": {
1514
1523
"description": "When the video was published.",
1515
1524
"type": "string"
1516
1525
},
1517
1526
"title": {
1518
1527
"description": "Video title.",
1519
1528
"type": "string"
1520
1529
},
1521
1530
"videoId": {
1522
1531
"description": "YouTube video ID.",
1523
1532
"type": "string"
1524
1533
}
1525
1534
},
1526
1535
"required": [
1527
1536
"videoId",
1528
1537
"title",
1529
1538
"publishedAt"
1530
1539
],
1531
1540
"type": "object"
1532
1541
}
1533
1542
},
1534
1543
"id": "me.linkna.linkinbio",
1535
1544
"lexicon": 1
1536
1545
}