social bookmarking for atproto
1{ 2 "openapi": "3.1.1", 3 "info": { 4 "title": "Clippr AppView API", 5 "version": "1.0.1", 6 "description": "API reference documentation for Clippr's backend.", 7 "license": { 8 "name": "GNU Affero General Public License v3.0 only", 9 "identifier": "AGPL-3.0-only" 10 } 11 }, 12 "servers": [ 13 { 14 "url": "http://localhost:9090", 15 "description": "Development server" 16 }, 17 { 18 "url": "https://api.clippr.social", 19 "description": "Production server" 20 } 21 ], 22 "tags": [ 23 { 24 "name": "Clips", 25 "description": "API paths that relate to user bookmarks, or 'clips'." 26 }, 27 { 28 "name": "Tags", 29 "description": "API paths that relate to user tags." 30 }, 31 { 32 "name": "Profile", 33 "description": "API paths that relate to user profiles." 34 }, 35 { 36 "name": "Misc", 37 "description": "API paths that don't fit into any other category." 38 } 39 ], 40 "paths": { 41 "/xrpc/social.clippr.actor.getPreferences": { 42 "get": { 43 "tags": ["Profile"], 44 "summary": "Get a user's preferences", 45 "operationId": "social.clippr.actor.getPreferences", 46 "description": "Get a user's private preferences. Requires authentication.", 47 "security": [ 48 { 49 "Bearer": [] 50 } 51 ], 52 "responses": { 53 "200": { 54 "description": "OK", 55 "content": { 56 "application/json": { 57 "schema": { 58 "$ref": "#/components/schemas/social.clippr.actor.defs.preferences" 59 } 60 } 61 } 62 }, 63 "400": { 64 "description": "Bad Request", 65 "content": { 66 "application/json": { 67 "schema": { 68 "type": "object", 69 "properties": { 70 "error": { 71 "type": "string", 72 "description": "A general error code", 73 "oneOf": [ 74 { 75 "const": "InvalidRequest" 76 }, 77 { 78 "const": "ExpiredToken" 79 }, 80 { 81 "const": "InvalidToken" 82 } 83 ] 84 }, 85 "message": { 86 "type": "string", 87 "description": "A detailed description of the error" 88 } 89 } 90 } 91 } 92 } 93 }, 94 "401": { 95 "description": "Unauthorized", 96 "content": { 97 "application/json": { 98 "schema": { 99 "type": "object", 100 "properties": { 101 "error": { 102 "type": "string", 103 "description": "A general error code", 104 "oneOf": [ 105 { 106 "const": "AuthMissing" 107 } 108 ] 109 }, 110 "message": { 111 "type": "string", 112 "description": "A detailed description of the error" 113 } 114 } 115 } 116 } 117 } 118 } 119 } 120 } 121 }, 122 "/xrpc/social.clippr.actor.getProfile": { 123 "get": { 124 "tags": ["Profile"], 125 "summary": "Get a profile", 126 "operationId": "social.clippr.actor.getProfile", 127 "description": "Get a user's profile based on a given DID or handle.", 128 "parameters": [ 129 { 130 "name": "actor", 131 "in": "query", 132 "description": "Handle or DID of account to fetch profile of", 133 "required": true, 134 "content": { 135 "schema": { 136 "type": "string", 137 "description": "Handle or DID of account to fetch profile of", 138 "format": "at-identifier" 139 } 140 }, 141 "deprecated": false, 142 "allowEmptyValue": false 143 } 144 ], 145 "responses": { 146 "200": { 147 "description": "OK", 148 "content": { 149 "application/json": { 150 "schema": { 151 "type": "object", 152 "$ref": "#/components/schemas/social.clippr.actor.defs.profileView" 153 } 154 } 155 } 156 }, 157 "400": { 158 "description": "Bad Request", 159 "content": { 160 "application/json": { 161 "schema": { 162 "type": "object", 163 "properties": { 164 "error": { 165 "type": "string", 166 "description": "A general error code", 167 "oneOf": [ 168 { 169 "const": "InvalidRequest" 170 } 171 ] 172 }, 173 "message": { 174 "type": "string", 175 "description": "A detailed description of the error" 176 } 177 } 178 } 179 } 180 } 181 } 182 } 183 } 184 }, 185 "/xrpc/social.clippr.actor.putPreferences": { 186 "post": { 187 "tags": ["Profile"], 188 "summary": "Set a user's preferences", 189 "operationId": "social.clippr.actor.putPreferences", 190 "description": "Sets the private preferences attached to the account. Requires authentication.", 191 "security": [ 192 { 193 "Bearer": [] 194 } 195 ], 196 "requestBody": { 197 "required": true, 198 "content": { 199 "application/json": { 200 "schema": { 201 "type": "object", 202 "properties": { 203 "preferences": { 204 "$ref": "#/components/schemas/social.clippr.actor.defs.preferences" 205 } 206 } 207 } 208 } 209 } 210 }, 211 "responses": { 212 "200": { 213 "description": "OK" 214 }, 215 "400": { 216 "description": "Bad Request", 217 "content": { 218 "application/json": { 219 "schema": { 220 "type": "object", 221 "properties": { 222 "error": { 223 "type": "string", 224 "oneOf": [ 225 { 226 "const": "InvalidRequest" 227 }, 228 { 229 "const": "ExpiredToken" 230 }, 231 { 232 "const": "InvalidToken" 233 } 234 ], 235 "description": "A general error code" 236 }, 237 "message": { 238 "type": "string", 239 "description": "A detailed description of the error" 240 } 241 } 242 } 243 } 244 } 245 }, 246 "401": { 247 "description": "Unauthorized", 248 "content": { 249 "application/json": { 250 "schema": { 251 "type": "object", 252 "properties": { 253 "error": { 254 "type": "string", 255 "description": "A general error code", 256 "oneOf": [ 257 { 258 "const": "AuthMissing" 259 } 260 ] 261 }, 262 "message": { 263 "type": "string", 264 "description": "A detailed description of the error" 265 } 266 } 267 } 268 } 269 } 270 } 271 } 272 } 273 }, 274 "/xrpc/social.clippr.actor.searchClips": { 275 "get": { 276 "tags": ["Clips"], 277 "summary": "Search clips", 278 "operationId": "social.clippr.actor.searchClips", 279 "description": "Find clips matching search criteria.", 280 "parameters": [ 281 { 282 "name": "q", 283 "in": "query", 284 "description": "Search query string", 285 "required": true, 286 "schema": { 287 "type": "string", 288 "description": "Search query string" 289 } 290 }, 291 { 292 "name": "limit", 293 "in": "query", 294 "description": "How many clips to return in the query output", 295 "required": false, 296 "schema": { 297 "type": "integer", 298 "minimum": 1, 299 "maximum": 100, 300 "default": 25 301 } 302 }, 303 { 304 "name": "actor", 305 "in": "query", 306 "description": "An actor to filter results to", 307 "required": false, 308 "schema": { 309 "type": "string", 310 "description": "An actor to filter results to", 311 "format": "at-identifier" 312 } 313 }, 314 { 315 "name": "cursor", 316 "in": "query", 317 "description": "A parameter to paginate results", 318 "required": false, 319 "schema": { 320 "type": "string", 321 "description": "A parameter to paginate results" 322 } 323 } 324 ], 325 "responses": { 326 "200": { 327 "description": "OK", 328 "content": { 329 "application/json": { 330 "schema": { 331 "type": "object", 332 "properties": { 333 "cursor": { 334 "type": "string", 335 "description": "A parameter to paginate results" 336 }, 337 "clips": { 338 "type": "array", 339 "items": { 340 "$ref": "#/components/schemas/social.clippr.feed.defs.clipView" 341 } 342 } 343 } 344 } 345 } 346 } 347 }, 348 "400": { 349 "description": "Bad Request", 350 "content": { 351 "application/json": { 352 "schema": { 353 "type": "object", 354 "properties": { 355 "error": { 356 "type": "string", 357 "description": "A general error code", 358 "oneOf": [ 359 { 360 "const": "InvalidRequest" 361 } 362 ] 363 }, 364 "message": { 365 "type": "string", 366 "description": "A detailed description of the error" 367 } 368 } 369 } 370 } 371 } 372 } 373 } 374 } 375 }, 376 "/xrpc/social.clippr.actor.searchProfiles": { 377 "get": { 378 "tags": ["Profile"], 379 "summary": "Search profiles", 380 "operationId": "social.clippr.actor.searchProfiles", 381 "description": "Find profiles matching search criteria.", 382 "parameters": [ 383 { 384 "name": "q", 385 "in": "query", 386 "description": "Search query string", 387 "required": false, 388 "schema": { 389 "type": "string", 390 "description": "Search query string" 391 } 392 }, 393 { 394 "name": "limit", 395 "in": "query", 396 "description": "The number of profiles to be returned in the query", 397 "required": false, 398 "schema": { 399 "type": "integer", 400 "minimum": 1, 401 "maximum": 100, 402 "default": 25 403 } 404 }, 405 { 406 "name": "cursor", 407 "in": "query", 408 "description": "A parameter used for pagination", 409 "required": false, 410 "schema": { 411 "type": "string", 412 "description": "A parameter used for pagination" 413 } 414 } 415 ], 416 "responses": { 417 "200": { 418 "description": "OK", 419 "content": { 420 "application/json": { 421 "schema": { 422 "type": "object", 423 "properties": { 424 "cursor": { 425 "type": "string", 426 "description": "A parameter used for pagination" 427 }, 428 "actors": { 429 "type": "array", 430 "items": { 431 "$ref": "#/components/schemas/social.clippr.actor.defs.profileView" 432 } 433 } 434 } 435 } 436 } 437 } 438 }, 439 "400": { 440 "description": "Bad Request", 441 "content": { 442 "application/json": { 443 "schema": { 444 "type": "object", 445 "properties": { 446 "error": { 447 "type": "string", 448 "description": "A general error code", 449 "oneOf": [ 450 { 451 "const": "InvalidRequest" 452 } 453 ] 454 }, 455 "message": { 456 "type": "string", 457 "description": "A detailed description of the error" 458 } 459 } 460 } 461 } 462 } 463 } 464 } 465 } 466 }, 467 "/xrpc/social.clippr.actor.searchTags": { 468 "get": { 469 "tags": ["Tags"], 470 "summary": "Search tags", 471 "operationId": "social.clippr.actor.searchTags", 472 "description": "Find tags matching search criteria.", 473 "parameters": [ 474 { 475 "name": "q", 476 "in": "query", 477 "description": "Search query string", 478 "required": true, 479 "schema": { 480 "type": "string", 481 "description": "Search query string" 482 } 483 }, 484 { 485 "name": "limit", 486 "in": "query", 487 "description": "How many tags to return in the query output", 488 "required": false, 489 "schema": { 490 "type": "integer", 491 "minimum": 1, 492 "maximum": 100, 493 "default": 25 494 } 495 }, 496 { 497 "name": "actor", 498 "in": "query", 499 "description": "An actor to filter results to", 500 "required": false, 501 "schema": { 502 "type": "string", 503 "description": "An actor to filter results to", 504 "format": "at-identifier" 505 } 506 }, 507 { 508 "name": "cursor", 509 "in": "query", 510 "description": "A parameter to paginate results", 511 "required": false, 512 "schema": { 513 "type": "string", 514 "description": "A parameter to paginate results" 515 } 516 } 517 ], 518 "responses": { 519 "200": { 520 "description": "OK", 521 "content": { 522 "application/json": { 523 "schema": { 524 "type": "object", 525 "properties": { 526 "cursor": { 527 "type": "string", 528 "description": "A parameter to paginate results" 529 }, 530 "tags": { 531 "type": "array", 532 "items": { 533 "$ref": "#/components/schemas/social.clippr.feed.defs.tagView" 534 } 535 } 536 } 537 } 538 } 539 } 540 }, 541 "400": { 542 "description": "Bad Request", 543 "content": { 544 "application/json": { 545 "schema": { 546 "type": "object", 547 "properties": { 548 "error": { 549 "type": "string", 550 "description": "A general error code", 551 "oneOf": [ 552 { 553 "const": "InvalidRequest" 554 } 555 ] 556 }, 557 "message": { 558 "type": "string", 559 "description": "A detailed description of the error" 560 } 561 } 562 } 563 } 564 } 565 } 566 } 567 } 568 }, 569 "/xrpc/social.clippr.feed.getClips": { 570 "get": { 571 "tags": ["Clips"], 572 "summary": "Get clips", 573 "operationId": "social.clippr.feed.getClips", 574 "description": "Get the hydrated views of a list of clips from their AT URIs.", 575 "parameters": [ 576 { 577 "name": "uris", 578 "in": "query", 579 "description": "List of tag AT-URIs to return hydrated views for", 580 "required": true, 581 "schema": { 582 "type": "array", 583 "items": { 584 "type": "string", 585 "format": "at-uri" 586 }, 587 "maxItems": 25 588 } 589 } 590 ], 591 "responses": { 592 "200": { 593 "description": "OK", 594 "content": { 595 "application/json": { 596 "schema": { 597 "type": "array", 598 "items": { 599 "$ref": "#/components/schemas/social.clippr.feed.defs.clipView" 600 } 601 } 602 } 603 } 604 }, 605 "400": { 606 "description": "Bad Request", 607 "content": { 608 "application/json": { 609 "schema": { 610 "type": "object", 611 "properties": { 612 "error": { 613 "type": "string", 614 "description": "A general error code", 615 "oneOf": [ 616 { 617 "const": "InvalidRequest" 618 } 619 ] 620 }, 621 "message": { 622 "type": "string", 623 "description": "A detailed description of the error" 624 } 625 } 626 } 627 } 628 } 629 } 630 } 631 } 632 }, 633 "/xrpc/social.clippr.feed.getTags": { 634 "get": { 635 "tags": ["Tags"], 636 "summary": "Get tags", 637 "operationId": "social.clippr.feed.getTags", 638 "description": "Get a the hydrated views of a list of tags from their AT URIs.", 639 "parameters": [ 640 { 641 "name": "uris", 642 "in": "query", 643 "description": "List of tag AT-URIs to return hydrated views for", 644 "required": true, 645 "schema": { 646 "type": "array", 647 "items": { 648 "type": "string", 649 "format": "at-uri" 650 }, 651 "maxItems": 25 652 } 653 } 654 ], 655 "responses": { 656 "200": { 657 "description": "OK", 658 "content": { 659 "application/json": { 660 "schema": { 661 "type": "array", 662 "items": { 663 "$ref": "#/components/schemas/social.clippr.feed.defs.tagView" 664 } 665 } 666 } 667 } 668 }, 669 "400": { 670 "description": "Bad Request", 671 "content": { 672 "application/json": { 673 "schema": { 674 "type": "object", 675 "properties": { 676 "error": { 677 "type": "string", 678 "description": "A general error code", 679 "oneOf": [ 680 { 681 "const": "InvalidRequest" 682 } 683 ] 684 }, 685 "message": { 686 "type": "string", 687 "description": "A detailed description of the error" 688 } 689 } 690 } 691 } 692 } 693 } 694 } 695 } 696 }, 697 "/xrpc/social.clippr.feed.getProfileClips": { 698 "get": { 699 "tags": ["Clips"], 700 "summary": "Get a profile's clip feed", 701 "operationId": "social.clippr.feed.getProfileClips", 702 "description": "Get a view of a profile's reverse-chronological clips feed.", 703 "parameters": [ 704 { 705 "name": "actor", 706 "in": "query", 707 "description": "An actor to get feed data from", 708 "required": true, 709 "schema": { 710 "type": "string", 711 "description": "An actor to get feed data from", 712 "format": "at-identifier" 713 } 714 }, 715 { 716 "name": "limit", 717 "in": "query", 718 "description": "How many results to return with the query", 719 "required": false, 720 "schema": { 721 "type": "integer", 722 "minimum": 1, 723 "maximum": 100, 724 "default": 50 725 } 726 }, 727 { 728 "name": "cursor", 729 "in": "query", 730 "description": "A parameter to paginate results", 731 "required": false, 732 "schema": { 733 "type": "string", 734 "description": "A parameter to paginate results" 735 } 736 }, 737 { 738 "name": "filter", 739 "in": "query", 740 "description": "What types to include in response", 741 "required": false, 742 "schema": { 743 "type": "string", 744 "description": "What types of clips to include in response", 745 "default": "all_clips", 746 "enum": ["all_clips", "tagged_clips", "untagged_clips"] 747 } 748 } 749 ], 750 "responses": { 751 "200": { 752 "description": "OK", 753 "content": { 754 "application/json": { 755 "schema": { 756 "type": "object", 757 "properties": { 758 "cursor": { 759 "type": "string" 760 }, 761 "feed": { 762 "type": "array", 763 "items": { 764 "$ref": "#/components/schemas/social.clippr.feed.defs.clipView" 765 } 766 } 767 } 768 } 769 } 770 } 771 }, 772 "400": { 773 "description": "Bad Request", 774 "content": { 775 "application/json": { 776 "schema": { 777 "type": "object", 778 "properties": { 779 "error": { 780 "type": "string", 781 "description": "A general error code", 782 "oneOf": [ 783 { 784 "const": "InvalidRequest" 785 } 786 ] 787 }, 788 "message": { 789 "type": "string", 790 "description": "A detailed description of the error" 791 } 792 } 793 } 794 } 795 } 796 } 797 } 798 } 799 }, 800 "/xrpc/social.clippr.feed.getProfileTags": { 801 "get": { 802 "tags": ["Tags"], 803 "summary": "Get a profile's tag feed", 804 "operationId": "social.clippr.feed.getProfileTags", 805 "description": "Get a view of a profile's reverse-chronological clips feed.", 806 "parameters": [ 807 { 808 "name": "actor", 809 "in": "query", 810 "description": "An actor to get feed data from", 811 "required": true, 812 "schema": { 813 "type": "string", 814 "description": "An actor to get feed data from", 815 "format": "at-identifier" 816 } 817 }, 818 { 819 "name": "limit", 820 "in": "query", 821 "description": "How many results to return with the query", 822 "required": false, 823 "schema": { 824 "type": "integer", 825 "minimum": 1, 826 "maximum": 100, 827 "default": 50 828 } 829 }, 830 { 831 "name": "cursor", 832 "in": "query", 833 "description": "A parameter to paginate results", 834 "required": false, 835 "schema": { 836 "type": "string", 837 "description": "A parameter to paginate results" 838 } 839 } 840 ], 841 "responses": { 842 "200": { 843 "description": "OK", 844 "content": { 845 "application/json": { 846 "schema": { 847 "type": "object", 848 "properties": { 849 "cursor": { 850 "type": "string" 851 }, 852 "feed": { 853 "type": "array", 854 "items": { 855 "$ref": "#/components/schemas/social.clippr.feed.defs.tagView" 856 } 857 } 858 } 859 } 860 } 861 } 862 }, 863 "400": { 864 "description": "Bad Request", 865 "content": { 866 "application/json": { 867 "schema": { 868 "type": "object", 869 "properties": { 870 "error": { 871 "type": "string", 872 "description": "A general error code", 873 "oneOf": [ 874 { 875 "const": "InvalidRequest" 876 } 877 ] 878 }, 879 "message": { 880 "type": "string", 881 "description": "A detailed description of the error" 882 } 883 } 884 } 885 } 886 } 887 } 888 } 889 } 890 }, 891 "/xrpc/social.clippr.feed.getTagList": { 892 "get": { 893 "tags": ["Tags"], 894 "summary": "Get a profile's tag list", 895 "operationId": "social.clippr.feed.getProfileTags", 896 "description": "Get a profile's complete list of tags.", 897 "parameters": [ 898 { 899 "name": "actor", 900 "in": "query", 901 "description": "An actor to fetch the tag list from", 902 "required": false, 903 "schema": { 904 "type": "string", 905 "description": "An actor to fetch the tag list from", 906 "format": "at-identifier" 907 } 908 } 909 ], 910 "responses": { 911 "200": { 912 "description": "OK", 913 "content": { 914 "application/json": { 915 "schema": { 916 "type": "object", 917 "properties": { 918 "tags": { 919 "type": "array", 920 "items": { 921 "$ref": "#/components/schemas/social.clippr.feed.defs.tagView" 922 } 923 } 924 } 925 } 926 } 927 } 928 }, 929 "400": { 930 "description": "Bad Request", 931 "content": { 932 "application/json": { 933 "schema": { 934 "type": "object", 935 "properties": { 936 "error": { 937 "type": "string", 938 "description": "A general error code", 939 "oneOf": [ 940 { 941 "error": "InvalidRequest" 942 } 943 ] 944 }, 945 "message": { 946 "type": "string", 947 "description": "A detailed description of the error" 948 } 949 } 950 } 951 } 952 } 953 } 954 } 955 } 956 }, 957 "/xrpc/_health": { 958 "get": { 959 "summary": "Health check", 960 "description": "Check the health of the server. If it is functioning properly, you will receive the server's version number.", 961 "responses": { 962 "200": { 963 "description": "OK", 964 "content": { 965 "application/json": { 966 "schema": { 967 "type": "object", 968 "properties": { 969 "version": { 970 "type": "string", 971 "description": "The version number of the AppView." 972 } 973 } 974 } 975 } 976 } 977 } 978 }, 979 "tags": ["Misc"] 980 } 981 } 982 }, 983 "components": { 984 "schemas": { 985 "com.atproto.repo.strongRef": { 986 "type": "object", 987 "required": ["uri", "cid"], 988 "properties": { 989 "uri": { 990 "type": "string", 991 "format": "at-uri" 992 }, 993 "cid": { 994 "type": "string", 995 "format": "cid" 996 } 997 } 998 }, 999 "social.clippr.actor.defs.profileView": { 1000 "type": "object", 1001 "description": "A view of an actor's profile", 1002 "required": ["did", "handle", "displayName"], 1003 "properties": { 1004 "did": { 1005 "type": "string", 1006 "description": "The DID of the profile", 1007 "format": "did" 1008 }, 1009 "handle": { 1010 "type": "string", 1011 "description": "The handle of the profile", 1012 "format": "handle" 1013 }, 1014 "displayName": { 1015 "type": "string", 1016 "description": "The display name associated to the profile", 1017 "maxLength": 64 1018 }, 1019 "description": { 1020 "type": "string", 1021 "description": "The biography associated to the profile", 1022 "maxLength": 500 1023 }, 1024 "avatar": { 1025 "type": "string", 1026 "description": "A link to the profile's avatar", 1027 "format": "uri" 1028 }, 1029 "createdAt": { 1030 "type": "string", 1031 "description": "When the profile record was first created", 1032 "format": "date-time" 1033 } 1034 } 1035 }, 1036 "social.clippr.actor.defs.preferences": { 1037 "type": "array", 1038 "items": { 1039 "oneOf": [ 1040 { 1041 "$ref": "#/components/schemas/social.clippr.actor.defs.publishingScopesPref" 1042 } 1043 ] 1044 } 1045 }, 1046 "social.clippr.actor.defs.publishingScopesPref": { 1047 "type": "object", 1048 "description": "Preferences for a user's publishing scopes", 1049 "required": ["defaultScope"], 1050 "properties": { 1051 "defaultScope": { 1052 "type": "string", 1053 "description": "What publishing scope to mark a clip as by default", 1054 "enum": ["public", "unlisted"] 1055 } 1056 } 1057 }, 1058 "social.clippr.feed.defs.clipView": { 1059 "type": "object", 1060 "description": "A view of a single bookmark (or 'clip')", 1061 "required": ["uri", "cid", "author", "record", "indexedAt"], 1062 "properties": { 1063 "uri": { 1064 "type": "string", 1065 "description": "The AT-URI of the clip", 1066 "format": "at-uri" 1067 }, 1068 "cid": { 1069 "type": "string", 1070 "description": "The CID of the clip", 1071 "format": "cid" 1072 }, 1073 "author": { 1074 "description": "A reference to the actor's profile", 1075 "$ref": "#/components/schemas/social.clippr.actor.defs.profileView" 1076 }, 1077 "record": { 1078 "type": "object", 1079 "description": "The raw record of the clip" 1080 }, 1081 "indexedAt": { 1082 "type": "string", 1083 "description": "The time in which the clip's record was indexed by the AppView", 1084 "format": "date-time" 1085 } 1086 } 1087 }, 1088 "social.clippr.feed.defs.tagView": { 1089 "type": "object", 1090 "description": "A view of a single tag", 1091 "required": ["uri", "cid", "author", "record", "indexedAt"], 1092 "properties": { 1093 "uri": { 1094 "type": "string", 1095 "description": "The AT-URI to the tag", 1096 "format": "at-uri" 1097 }, 1098 "cid": { 1099 "type": "string", 1100 "description": "The CID of the tag", 1101 "format": "cid" 1102 }, 1103 "author": { 1104 "description": "A reference to the actor's profile", 1105 "$ref": "#/components/schemas/social.clippr.actor.defs.profileView" 1106 }, 1107 "record": { 1108 "type": "object", 1109 "description": "The raw record of the clip" 1110 }, 1111 "indexedAt": { 1112 "type": "string", 1113 "description": "The time in which the tag's record was indexed by the AppView", 1114 "format": "date-time" 1115 } 1116 } 1117 }, 1118 "social.clippr.actor.profile": { 1119 "type": "object", 1120 "required": ["createdAt", "displayName"], 1121 "properties": { 1122 "displayName": { 1123 "type": "string", 1124 "description": "A display name to be shown on a profile", 1125 "maxLength": 64 1126 }, 1127 "description": { 1128 "type": "string", 1129 "description": "Text for user to describe themselves", 1130 "maxLength": 500 1131 }, 1132 "avatar": { 1133 "type": "blob", 1134 "maxSize": 1000000, 1135 "description": "Image to show on user's profiles" 1136 }, 1137 "createdAt": { 1138 "type": "string", 1139 "description": "The creation date of the profile", 1140 "format": "date-time" 1141 } 1142 } 1143 }, 1144 "social.clippr.feed.clip": { 1145 "type": "object", 1146 "required": ["url", "title", "description", "unlisted", "createdAt"], 1147 "properties": { 1148 "url": { 1149 "type": "string", 1150 "description": "The URL of the bookmark. Cannot be left empty or be modified after creation.", 1151 "format": "uri", 1152 "maxLength": 2000 1153 }, 1154 "title": { 1155 "type": "string", 1156 "description": "The title of the bookmark. If left empty, reuse the URL.", 1157 "maxLength": 2048 1158 }, 1159 "description": { 1160 "type": "string", 1161 "description": "A description of the bookmark's content. This should be ripped from the URL metadata and be static for all records using the URL.", 1162 "maxLength": 4096 1163 }, 1164 "notes": { 1165 "type": "string", 1166 "description": "User-written notes for the bookmark. Public and personal.", 1167 "maxLength": 10000 1168 }, 1169 "tags": { 1170 "type": "array", 1171 "description": "An array of tags. A format of solely alphanumeric characters and dashes should be used.", 1172 "items": { 1173 "$ref": "#/components/schemas/com.atproto.repo.strongRef" 1174 } 1175 }, 1176 "unlisted": { 1177 "type": "boolean", 1178 "description": "Whether the bookmark can be used for feed indexing and aggregation" 1179 }, 1180 "unread": { 1181 "type": "boolean", 1182 "description": "Whether the bookmark has been read by the user", 1183 "default": true 1184 }, 1185 "languages": { 1186 "type": "array", 1187 "items": { 1188 "type": "string", 1189 "format": "language" 1190 }, 1191 "maxItems": 5 1192 }, 1193 "createdAt": { 1194 "type": "string", 1195 "description": "Client-declared timestamp when the bookmark is created", 1196 "format": "date-time" 1197 } 1198 } 1199 }, 1200 "social.clippr.feed.tag": { 1201 "type": "object", 1202 "required": ["name", "createdAt"], 1203 "properties": { 1204 "name": { 1205 "type": "string", 1206 "description": "A de-duplicated string containing the name of the tag", 1207 "maxLength": 64 1208 }, 1209 "color": { 1210 "type": "string", 1211 "description": "A hexadecimal color code", 1212 "maxLength": 7 1213 }, 1214 "description": { 1215 "type": "string", 1216 "description": "A description of the tag for additional context", 1217 "maxLength": 5000 1218 }, 1219 "createdAt": { 1220 "type": "string", 1221 "description": "A client-defined timestamp for the creation of the tag", 1222 "format": "date-time" 1223 } 1224 } 1225 } 1226 } 1227 } 1228}