{"id":43023188,"url":"https://github.com/cdom27/art-api","last_synced_at":"2026-01-31T06:38:59.968Z","repository":{"id":327486327,"uuid":"980227696","full_name":"cdom27/art-api","owner":"cdom27","description":"REST API built with Express, TypeScript, PSQL, and Key Authentication","archived":false,"fork":false,"pushed_at":"2026-01-18T07:51:21.000Z","size":1189,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-18T13:50:59.253Z","etag":null,"topics":["bcrypt","drizzle-orm","express-rate-limit","expressjs","gcp","google-cloud-platform","nodecrypto","postgresql","rest-api","typescript"],"latest_commit_sha":null,"homepage":"https://openart.work","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cdom27.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-05-08T19:26:15.000Z","updated_at":"2025-12-15T08:00:53.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/cdom27/art-api","commit_stats":null,"previous_names":["cdom27/art-api"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/cdom27/art-api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdom27%2Fart-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdom27%2Fart-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdom27%2Fart-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdom27%2Fart-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cdom27","download_url":"https://codeload.github.com/cdom27/art-api/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdom27%2Fart-api/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28931389,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-31T04:05:25.756Z","status":"ssl_error","status_checked_at":"2026-01-31T04:02:35.005Z","response_time":128,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bcrypt","drizzle-orm","express-rate-limit","expressjs","gcp","google-cloud-platform","nodecrypto","postgresql","rest-api","typescript"],"created_at":"2026-01-31T06:38:59.356Z","updated_at":"2026-01-31T06:38:59.947Z","avatar_url":"https://github.com/cdom27.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Open Artwork API\n\n**Open Artwork** is a free RESTful Web API that provides structured metadata of the 50 most influential artists in history, along with selected public domain artworks.\n\nDevelopers can access detailed artist bios, artwork data, and run keyword-based search queries. Whether you’re building educational apps, creative galleries, or simply experimenting, this API is a reliable resource.\n\nYou can get started by [generating a free public API key](https://openart.work). No sign-in or credit card required.\n\n---\n\n## Table of Contents\n\n- [Tech Stack](#tech-stack)\n- [Infrastructure Overview](#infrastructure-overview)\n- [API Information](#api-information)\n- [TypeScript Types](#typescript-types)\n- [Usage](#usage)\n  - [Getting Started](#getting-started)\n  - [Making Requests](#making-requests)\n- [RESTful Endpoints](#restful-endpoints)\n  - [Artists](#artists)\n  - [Artworks](#artworks)\n  - [Search](#search)\n- [Projects Using Art API](#projects-using-art-api)\n- [Plans for v2](#plans-for-v2)\n- [Author](#author)\n- [License](#license)\n\n---\n\n## Tech Stack\n\nThe current API version (v1) is built with:\n\n- Node.js / Express.js\n- TypeScript\n- PostgreSQL\n- Drizzle ORM\n- Zod\n- Bcrypt\n\n---\n\n## Infrastructure Overview\n\nThe API is hosted on **Google Cloud Platform**, using:\n\n- Cloud Run (Dockerfile and GitHub Actions)\n- Application Load Balancer (with a CDN for both the client and signed image asset urls)\n- Cloud Storage\n\n---\n\n## API Information\n\n- **Version**: v1\n- **Base URL**: `https://openart.work/api/v1/`\n- **Authentication**: Requires a [free API key](https://openart.work). Include it in the request header as 'x-api-key'.\n- **Rate Limiting**:\n  - 200 requests per 15 minutes\n  - After 75 requests, a delay of up to 3 seconds per request is applied\n- **Image Licensing**: All images served are from the public domain.\n- **Search**: Currently supports **keyword-based** filtering. Full-text search is planned for v2.\n- If you use this API in a public or production setting, please consider linking to this repo for credit.\n\nWe welcome contributions in the form of data collection (public domain only) or code improvements.\n\n---\n\n## TypeScript Types\n\nThese types describe the shape of API responses and entities:\n\n```ts\ntype Artist = {\n  id: number;\n  name: string;\n  genre: string;\n  nationality: string;\n  bio: string;\n  wikipedia: string; // Extended biography URL\n  birthYear: string;\n  deathYear: string;\n};\n\ntype Artwork = {\n  id: number;\n  title: string;\n  medium: string;\n  inferredYear: string;\n  fullImageUrl: string;\n  thumbnailImageUrl: string;\n  artistId: number;\n};\n\ntype SearchResult = {\n  artists: Artist[];\n  artworks: Artwork[];\n};\n\ntype ApiResponse\u003cT\u003e = {\n  status: number;\n  message: string;\n  data: T | null;\n};\n```\n\n---\n\n## Usage\n\nBefore making requests, generate your free [API key](https://openart.work).\n\n\u003e **Note:** All code snippets assume you're using **Vite with TypeScript**, which exposes `.env` variables via `import.meta.env` and uses the `VITE_` prefix. If you're using a different stack (e.g. Next.js, plain HTML/JS, SpringBoot) adapt accordingly as build tools differ in how they expose and manage environment variables.\n\n### Getting Started\n\nCreate a `.env` file in your root directory and add:\n\n```\nVITE_OA_API_BASE_URL=https://openart.work/api/v1\nVITE_OA_API_PUBLISHABLE_KEY=\u003cYOUR_API_KEY_HERE\u003e\n```\n\n---\n\n### Making Requests\n\nAll requests must include your API key in the **headers** of the request as `x-api-key`:\n\n#### Example: Find French artists\n\n```ts\nconst response = await fetch(\n  `${import.meta.env.VITE_ART_API_BASE_URL}/artists?nationality=French`,\n  {\n    method: 'GET',\n    headers: {\n      'Content-Type': 'application/json',\n      'x-api-key': import.meta.env.VITE_ART_API_PUBLISHABLE_KEY,\n    },\n  }\n);\n\nconst data: ApiResponse\u003cArtist[]\u003e = await response.json();\nconsole.log(data);\n```\n\n#### Example: Find artworks by title\n\n```ts\nconst response = await fetch(\n  `${import.meta.env.VITE_ART_API_BASE_URL}/artworks?title=lilies`,\n  {\n    method: 'GET',\n    headers: {\n      'Content-Type': 'application/json',\n      'x-api-key': import.meta.env.VITE_ART_API_PUBLISHABLE_KEY,\n    },\n  }\n);\n\nconst data: ApiResponse\u003cArtwork[]\u003e = await response.json();\nconsole.log(data);\n```\n\n---\n\n## Endpoints\n\n### Artists\n\n#### Query Parameters\n\n- `name` – Partial match (e.g., `name=van`)\n- `genre` – Exact match\n- `nationality` – Exact match\n- `birthYearMin`, `birthYearMax` – Filter by birth year\n- `deathYearMin`, `deathYearMax` – Filter by death year\n\n#### Artist Endpoints\n\n- `GET /artists`\n  Returns all artists ordered by `id` ascending.\n\n- `GET /artists/:id`\n  Returns a single artist by `id`.\n\n- `GET /artists/random`\n  Returns a random artist.\n\n- `GET /artists/:id/full`\n  Returns an artist and all their artworks.\n\n---\n\n### Artworks\n\n#### Query Parameters\n\n- `title` – Partial title match\n- `medium` – Exact match\n- `artistId` – Filter by artist ID\n\n#### Artwork Endpoints\n\n- `GET /artworks`\n  Returns all artworks ordered by `id`.\n\n- `GET /artworks/:id`\n  Returns a single artwork by `id`.\n\n- `GET /artworks/random`\n  Returns a random artwork.\n\n---\n\n### Search\n\nPerforms a global keyword-based search across both artists and artworks.\n\n#### Query Parameters\n\n- `q` – Keyword string (e.g., `q=van go`)\n- All parameters from [Artists](#artists) and [Artworks](#artworks) are supported\n\n#### Example: Search for data containing `monet` and `French`\n\n```ts\nconst response = await fetch(\n  `${import.meta.env.VITE_ART_API_BASE_URL}/search?q=monet\u0026nationality=French`,\n  {\n    method: 'GET',\n    headers: {\n      'Content-Type': 'application/json',\n      'x-api-key': import.meta.env.VITE_ART_API_PUBLISHABLE_KEY,\n    },\n  }\n);\n\nconst data: ApiResponse\u003cSearchResult\u003e = await response.json();\nconsole.log(data);\n```\n\n---\n\n## Projects Using Art API\n\nHave you built something with the Art API? Open a PR to be featured here.\n\n---\n\n## Plans for v2\n\nThe next release (v2) will prioritize developer experience, performance, and support for additional open data sources.\n\n**Planned features:**\n\n1. **Year Normalization**\n   Improve support for inferred or ambiguous artwork dates with partial range support (e.g., `1870s`, `early 1800s`).\n\n2. **Flexible Image Service**\n   New `fullImageUrl` and `thumbnailImageUrl` generation service with support for `width`, `height`, and `fileType` (e.g., WebP, JPEG).\n\n3. **More Open Sources**\n   Additional data sources will be integrated, with proper attribution listed in the documentation.\n\n---\n\n## Author\n\nMaintained by [@cdom27](https://github.com/cdom27).\nFeel free to open issues or suggest improvements.\n\n---\n\n## License\n\nThis project and API are licensed under the [MIT License](LICENSE).\nAll artwork images are sourced from the public domain.\n\n---\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcdom27%2Fart-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcdom27%2Fart-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcdom27%2Fart-api/lists"}