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