source.unsplash.com Saiu do Ar: O Post-Mortem e Todas as Formas de Substituí-lo

Descontinuado em 2021 com a promessa de que “os usos existentes continuarão funcionando”, desligado em junho de 2024, e ainda assim escrito em código novo até hoje. O post-mortem detalhado — e as três alternativas, incluindo o proxy que devolve a aleatoriedade sem chave.

Compartilhar
Uma fotografia em preto e branco de um smartphone com a tela rachada sobre uma superfície de madeira clara, com o logotipo da Unsplash aparecendo na tela danificada.
Foto via Unsplash

Um serviço de banco de imagens desligou um subdomínio, e dois anos depois ele ainda está quebrando sites de documentação, telas de login, exercícios de curso e código recém-gerado. Este é um post-mortem de uma URL — o que ela fazia, o que a matou e o que colocar no lugar — além de um olhar ponderado sobre a parte mais estranha da história: as máquinas que escrevem nosso código ainda não perceberam que ela sumiu.

As respostas HTTP, as duas entradas de changelog citadas palavra por palavra, os limites da API, os rastreadores de issues dos projetos que quebraram e as contagens do GitHub, npm e Stack Overflow vêm todos de fontes primárias, com o método de cada uma em as notas de rodapé. Se você só quer a correção, vá direto para a tabela de migração.

O que você recebe hoje, se ainda a solicita

Um comando, sem chave, reproduzível de qualquer máquina:

terminal
curl -I https://source.unsplash.com/random

HTTP/2 503
cache-control: no-cache, no-store
content-type: text/html; charset=utf-8
server: Heroku
via: 2.0 heroku-router
# corpo: um iframe apontando para herokucdn.com/error-pages/application-error.html

Nada disso é uma falha de DNS. source.unsplash.com ainda resolve — é um CNAME para um host herokudns.com — então a requisição é respondida, só que não por uma aplicação. Esse detalhe importa mais do que parece: um navegador que recebe um 503 rápido com corpo em HTML renderiza um placeholder de imagem quebrada, e qualquer código que leia response.ok ou um handler de onerror que você nunca escreveu segue o caminho de falha que você nunca testou.

Padrão de URL O que costumava retornar Hoje
source.unsplash.com/randomUma foto aleatória, qualquer tamanho503
source.unsplash.com/random/1600x900Uma foto aleatória, recortada no tamanho503
source.unsplash.com/1600x900/?apple,deskUma foto aleatória correspondente a termos de busca503
source.unsplash.com/featured/1600x900?natureUma foto aleatória em destaque503
source.unsplash.com/collection/190727/800x600Uma foto aleatória de uma coleção503
source.unsplash.com/user/scottwebb/1600x900Uma foto aleatória de um fotógrafo503
source.unsplash.com/dailyA foto do dia503

Verificado individualmente com curl -o /dev/null -w "%{http_code}". O recurso de busca foi desativado primeiro, conforme anunciado; hoje a aplicação inteira está fora do ar, então a distinção deixou de existir.

Três anos entre “descontinuado” e “desligado”

Os dois anúncios ainda podem ser lidos, em um único lugar, em unsplash.com/documentation/changelog. Citados na íntegra, porque a redação é a história inteira:

25 de novembro de 2021 — “Unsplash Source being deprecated”
“Unsplash Source is being deprecated. Existing uses will continue to work, however for new projects use the full Unsplash API.”

11 de junho de 2024 — “Unsplash Source sunset”
“Unsplash Source has been officially unsupported since its deprecation in 2021. As part of the final sunsetting, we will first wind down by disabling the search feature, and in the coming weeks turn off the application entirely. Existing uses of Source — particularly production-level ones — should migrate as soon as possible to the full Unsplash API.”

Lendo os dois em sequência, o modo de falha fica óbvio. O aviso de 2021 continha uma promessa (existing uses will continue to work) e nenhuma data. Um desenvolvedor que o leu em 2021 tinha todo motivo para deixar o código funcional em paz; um desenvolvedor que entrou em 2022 nunca o leu. O aviso de 2024 deu “as próximas semanas”, três anos depois, em uma página que ninguém havia marcado como favorita.

A Unsplash de fato publica uma política de descontinuação, e é uma política razoável — a documentação afirma que, para campos e endpoints publicamente documentados, as mudanças são anunciadas no changelog com pelo menos 3 semanas de aviso, e os endpoints retornam um cabeçalho Warning durante o período de descontinuação. O mesmo parágrafo contém a frase que explica por que nada disso protegeu o Source: “For any non-publicly documented fields or endpoints, we may make changes to these with no warning.” O Source nunca foi um endpoint da API documentada. Ele ficava fora da política que o teria protegido.

  • A lição prática não é “a Unsplash foi negligente”. É que uma URL que você pode usar sem ler nenhuma documentação é uma URL cuja política de descontinuação você também não leu.
  • A quebra veio antes do anúncio. Uma issue do Drupal aberta em 28 de novembro de 2022 já relata “I get always a Heroku application error”, dezoito meses antes da entrada de encerramento. É assim que esses serviços morrem: devagar, e depois em um anúncio que você nunca vê.

O anúncio é mais difícil de encontrar do que a interrupção

A descontinuação de 2021 foi publicada em changelog.unsplash.com, e essa é a URL que todo relato de bug contemporâneo cita — incluindo o do Drupal acima. Três medições:

  1. O endpoint HTTPS está quebrado. openssl s_client -connect changelog.unsplash.com:443 retorna tlsv1 alert internal error — o handshake falha antes que qualquer certificado seja apresentado. Todo link da era 2021, que era https://, está, portanto, morto em um navegador.
  2. Via HTTP simples ele redireciona, mas sem utilidade. Seguindo http://changelog.unsplash.com/deprecations/2021/11/25/source-deprecation.html, termina-se, dois saltos depois, em um 400 em unsplash.com/@documentation/changelog/deprecations/2021/11/25/source-deprecation/html — o caminho foi engolido pela rota de nome de usuário do site.
  3. O arquivo tem um buraco exatamente onde está o encerramento. A última captura bem-sucedida do changelog antigo pelo Wayback Machine é de 24 de março de 2024; a primeira captura do novo é de 23 de agosto de 2024. O encerramento foi anunciado em 11 de junho de 2024 — dentro dessa lacuna de cinco meses.

Nada disso é conspiração; é uma migração de CMS comum. Mas a consequência é real, e é o motivo deste artigo citar as duas entradas na íntegra: o registro primário de uma descontinuação deveria sobreviver àquilo que descontinua, e aqui ele quase não sobreviveu.

O que realmente quebrou

Não foram projetos paralelos. As falhas abaixo são entradas públicas de rastreadores de issues; os títulos, datas e estados vêm das APIs do GitHub e do drupal.org.

Projeto Issue Aberta em O que diz
MUI (Material UI) #42736 24 jun 2024 “[docs] Random Unsplash photo URL is no longer functional” — o template oficial Sign-in side vinha com uma imagem morta. Fechada três dias depois.
Nextcloud #115 17 jan 2023 “Migrate to Unsplash API” — o app de plano de fundo era construído sobre URIs do Source. Aberta por dezoito meses, fechada em 16 de julho de 2024.
sindresorhus/Actions #248 28 mai 2024 “Get Unsplash Image: 503 Error” — uma ação de Atalhos do iOS/macOS, quebrada duas semanas antes de o encerramento ser anunciado.
Drupal — Gin Login #3324054 28 nov 2022 “Unsplash has deprecated source.unsplash.com — this delays reCAPTCHA from loading, preventing users from logging in.”

Leia essa última linha de novo, porque é a que vale a pena internalizar. Uma imagem decorativa ao lado de um formulário de login — o recurso mais obviamente não crítico da página — degenerou em uma interrupção de autenticação, porque uma requisição lenta de terceiros ficava na frente do CAPTCHA de que o formulário de login precisava. Ninguém escreveu assim de propósito. Isso surgiu da ordem em que um navegador carrega as coisas.

Seu assistente de código não recebeu o recado

Aqui está a parte que transforma uma interrupção de 2024 em um problema de 2026. source.unsplash.com foi documentado, comentado em blogs, ensinado e copiado por cerca de oito anos. Todo esse texto está nos dados de treinamento dos modelos que hoje escrevem nosso código inicial — e texto não expira. Três contagens:

MediçãoValor em 30 ago 2026Como foi obtida
Arquivos contendo source.unsplash.com 3.344 API de busca de código do GitHub, q=source.unsplash.com (apenas código público indexado — um piso, não um total)
Repositórios em uma amostra de 100 arquivos criados depois do encerramento 12 de 77 Mesma consulta, 100 resultados, deduplicados para 77 repositórios, created_at comparado a 11 de jun de 2024
…e repositórios dessa amostra com commits nos últimos 12 meses 20 de 77 Repositórios ativos, não arquivados — incluindo elastic/kibana, cujo arquivo de demonstração ainda tem imageUrl: 'https://source.unsplash.com/64x64/?dingo'
Downloads mensais de unsplash-source-es6 23 API do registro npm — um wrapper para um serviço morto, publicado pela última vez em 2022, ainda sendo instalado
Posts do Stack Overflow que a mencionam 1.459 API do Stack Exchange, total de /search/excerpts

A evidência mais direta não está no código de aplicação — está nos prompts. O principal resultado para essa busca é uma biblioteca de prompts de sistema do GPT contendo a linha “please use unsplash API( https://source.unsplash.com/1280x720/?<PUT YOUR QUERY HERE>”. Essa instrução ainda está sendo copiada para novos assistentes hoje. O modelo não verifica a URL; foi instruído a usá-la, e todo exemplo que ele já viu concordava.

Então a falha de código gerado tem duas causas independentes, e corrigir uma não corrige a outra: dados de treinamento desatualizados e instruções desatualizadas escritas por humanos por cima deles. De qualquer forma, o sintoma é a mesma família de imagens que nunca carregam:

os padrões de imagem morta que vale a pena buscar
source.unsplash.com/random/1200x800   # 503 desde meados de 2024 — nunca mais volta
images.unsplash.com/photo-…           # CDN real, mas IDs memorizados podem não existir
via.placeholder.com/400               # retângulo cinza, enviado para produção
placehold.co/800x600                  # retângulo cinza, de propósito
picsum.photos/800/600                 # uma foto real, sem relação com sua página
/placeholder.png                      # um arquivo que nunca foi adicionado ao repositório

Uma nota de rodapé sobre a segunda linha dessa lista: enquanto escrevíamos este artigo, via.placeholder.com também não conseguiu completar um handshake TLS a partir da nossa rede de teste, e respondeu 403 via HTTP simples. Verifique a partir da sua própria rede antes de confiar nele — o fallback ao qual essas ferramentas recorrem pode ter sua própria história de interrupção.

Só o primeiro está quebrado. Os outros são piores de um jeito mais sutil: eles carregam, o layout parece pronto, e ninguém percebe que a página está ilustrada com nada em particular. E nada disso é específico de imagens — é o formato geral do problema. A visão de um modelo sobre a web é uma fotografia de um instante, e endpoints, flags de CLI, nomes de pacotes e planos gratuitos continuam mudando depois que o obturador se fecha.

A tabela de migração

Existem exatamente três destinos, e a forma honesta de apresentá-los é pelo que você abre mão. Escolha a coluna primeiro, depois leia sua linha.

URL antiga do Source A. URL fixa de CDNsem chave · sem aleatoriedade B. API da Unsplashchave · chamada no servidor C. Seu próprio proxychave oculta · aleatoriedade de volta
/random images.unsplash.com/photo-… — uma foto escolhida por você GET /photos/random /?w=1600
/random/1600x900 …?w=1600&h=900&fit=crop /photos/random + parâmetros do Imgix na URL retornada /?w=1600&h=900&fit=crop
/1600x900/?apple,desk Sem equivalente — escolha uma foto manualmente /photos/random?query=apple,desk /?query=apple,desk&w=1600
/featured/1600x900?nature Sem equivalente /photos/random?query=nature “featured” não tem sucessor /?query=nature&w=1600
/collection/67920491/1600x900 Sem equivalente /photos/random?collections=67920491 /?collections=67920491&w=1600
/user/scottwebb/1600x900 Sem equivalente /photos/random?username=scottwebb /?username=scottwebb&w=1600
/daily Fixe uma foto e alterne-a no seu build Sem equivalente — armazene em cache uma foto aleatória por 24 h você mesmo O mesmo, com o cache no proxy

A opção A é a que a maioria das pessoas realmente quer. Se a imagem era decorativa — um herói, um painel lateral de login, um plano de fundo de card — você nunca precisou de uma foto diferente a cada requisição. Escolha uma, mantenha a URL da CDN, e a página para de depender de qualquer coisa aleatória:

uma URL fixa e redimensionável da Unsplash — sem chave, sem chamada de API
<img src="https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=1600&h=900&fit=crop&auto=format"
     width="1600" height="900" alt="…">
# Parâmetros oficialmente suportados: w, h, crop, fit, fm, auto=format, q, dpr.
# Mantenha o parâmetro ixid que a API te deu — é ele que registra a visualização.

A opção B é o caminho oficial, e move a chamada para o servidor, porque um Client-ID em JavaScript de front-end é uma credencial publicada. Observe as duas regras que costumam pegar as pessoas de surpresa: collections/topics não podem ser combinados com query na mesma requisição, e count (máx. 30) muda o formato da resposta para um array mesmo quando é 1.

o substituto oficial de /random
curl "https://api.unsplash.com/photos/random?query=nature&orientation=landscape" \
  -H "Authorization: Client-ID YOUR_ACCESS_KEY" \
  -H "Accept-Version: v1"

# → JSON. A imagem fica em .urls.regular / .urls.raw (adicione w/h/fit você mesmo).
# → X-Ratelimit-Limit: 1000   X-Ratelimit-Remaining: 999

Opção C: reconstrua o Source, em cerca de quarenta linhas

Se o que você perdeu era genuinamente o comportamento — uma URL sem chave que retorna uma foto diferente a cada vez, usável direto em uma tag <img>, em um campo de CMS, ou em um site estático onde não há servidor — então você precisa rodar esse endpoint você mesmo. É um pequeno worker na frente da API, e as três coisas que fazem ele sobreviver ao contato com produção são o cache, a verificação de referrer e a passagem do restante da query string para a CDN.

worker.js — um endpoint sem chave no formato do Source, sobre /photos/random
// Cloudflare Workers. Em outros lugares (Deno Deploy, Val Town…) o formato é o mesmo,
// mas abra um cache nomeado com caches.open() em vez de caches.default.
// UNSPLASH_KEY permanece no servidor. Quem chama nunca a vê.
const ALLOWED = ["example.com", "www.example.com"];   // apenas seus domínios
const API_PARAMS = ["query", "collections", "topics", "username", "orientation"];
const TTL = 60;                                       // segundos — protege a cota por hora

const host = (value) => { try { return new URL(value).hostname; } catch { return null; } };

export default {
  async fetch(req, env, ctx) {
    // 0. Apenas GET: a Cache API recusa armazenar qualquer outra coisa, e um
    //    endpoint de imagem não tem outro verbo para responder.
    if (req.method !== "GET")
      return new Response("Method not allowed", { status: 405 });
    const url = new URL(req.url);

    // 1. Só suas próprias páginas podem incorporar isso — um endpoint público
    //    de foto aleatória na internet aberta é a cota de outra pessoa sendo gasta.
    const ref = req.headers.get("referer");       // ausente em vários clientes legítimos
    if (ref && !ALLOWED.includes(host(ref)))
      return new Response("Forbidden", { status: 403 });

    // 2. Cache por combinação de parâmetros, para que uma página com 12 imagens
    //    custe uma chamada de API por minuto em vez de doze por renderização.
    const cache = caches.default;
    const hit = await cache.match(req);
    if (hit) return hit;

    // 3. Pede à API oficial uma foto aleatória.
    const api = new URL("https://api.unsplash.com/photos/random");
    for (const p of API_PARAMS)
      if (url.searchParams.has(p)) api.searchParams.set(p, url.searchParams.get(p));

    const r = await fetch(api, { headers: {
      Authorization: "Client-ID " + env.UNSPLASH_KEY,
      "Accept-Version": "v1",
    }});
    // 403 aqui geralmente significa a cota por hora, não uma chave inválida — aumente o TTL, sem pânico.
    if (!r.ok) return new Response("Upstream " + r.status, { status: 502 });
    const photo = await r.json();

    // 4. Reconstrói a URL da imagem: mantém o ixid, adiciona os parâmetros de tamanho do chamador.
    const img = new URL(photo.urls.raw);          // .raw já traz o ixid
    for (const [k, v] of url.searchParams)
      if (!API_PARAMS.includes(k)) img.searchParams.set(k, v);  // w, h, fit, q…

    const res = new Response(null, { status: 302, headers: {
      Location: img.toString(),
      "Cache-Control": "public, max-age=" + TTL,
      // O crédito acompanha o redirecionamento; valores de cabeçalho devem ser ASCII, daí a codificação.
      "X-Photo-Credit": encodeURIComponent(photo.user.name + " on Unsplash"),
      "X-Photo-Link": photo.links.html,
    }});
    ctx.waitUntil(cache.put(req, res.clone()));
    return res;
  },
};

Migrar uma URL vira então um buscar-e-substituir, o que é exatamente o que torna essa opção interessante pelos vinte minutos que ela custa:

substituição um-para-um
- https://source.unsplash.com/collection/67920491/1600x900
+ https://img.example.com/?collections=67920491&w=1600&h=900&fit=crop

Duas observações de design, ambas custaram uma tarde ruim para alguém antes de serem anotadas. O redirecionamento (302), em vez de fazer proxy dos bytes, evita que você pague pela banda e mantém a visualização contada na CDN da Unsplash, que é o que as diretrizes pedem. E a verificação de Referer é deliberadamente permissiva quando o cabeçalho está ausente — muitos clientes legítimos o removem — mas ainda assim impede o caso óbvio de seu endpoint virar a API gratuita de imagens de outra pessoa.

As regras que você herda no momento em que usa a API

O Source não tinha regras porque não tinha conta. A API tem cinco que mudam como você projeta a solução, todas da documentação atual:

  • Os limites de taxa são por hora, e pequenos no início. 50 requisições/hora em modo demo; 1.000/hora depois que sua aplicação for aprovada para produção. Só as chamadas para api.unsplash.com contam — requisições de imagem para images.unsplash.com não contam. Leia X-Ratelimit-Remaining em cada resposta.
  • Hotlinking é obrigatório, não apenas permitido. A Unsplash exige que as URLs de imagem retornadas pela API sejam incorporadas diretamente, para que as visualizações da foto possam ser atribuídas ao fotógrafo. Espelhar o arquivo na sua própria CDN é a única otimização que você não tem liberdade de fazer.
  • Mantenha o parâmetro ixid. Redimensionar e recortar a URL retornada é esperado; remover o parâmetro que identifica sua aplicação não é.
  • Atribuição e rastreamento de download fazem parte do acordo — o fotógrafo e a Unsplash recebem crédito, e um “download” é reportado pelo endpoint de download da foto quando um usuário baixa o arquivo, um evento que você precisa disparar você mesmo.
  • Produtos distribuídos precisam de registro dinâmico de cliente. Se você distribui um plugin, um tema ou um CMS auto-hospedado, uma única chave compartilhada é tanto uma violação de política quanto um ponto único de falha; a API tem um fluxo de registro exatamente para esse caso.

Este é o momento de ser honesto sobre o escopo: se você já vai integrar uma API e uma chave de qualquer forma, a escolha de qual API de imagens fica subitamente aberta, e vale a pena gastar cinco minutos nisso antes de escrever o cliente. Comparamos as gratuitas — cotas, regras, comportamento de busca e formatos de resposta — em a comparação de APIs gratuitas de banco de imagens.

Se você só queria um placeholder, diga isso

Uma boa parte do uso do Source nunca teve a ver com a Unsplash. Era “coloque algo com formato de imagem aqui enquanto eu construo o layout”. Para isso, serviços sem chave ainda existem e são a resposta correta:

ServiçoChave?O que você recebeOnde ele para
Lorem Picsum Não Fotografias reais: picsum.photos/800/600, uma estável com /id/237/… ou /seed/xxx/…, além de ?grayscale e ?blur=1..10. Seu endpoint /v2/list credita a página e o autor de cada foto na Unsplash. Nenhum direcionamento de assunto. A foto não terá relação com sua página.
placehold.co Não Retângulos rotulados em qualquer tamanho — um preenchimento honesto de wireframe. É uma caixa cinza, e parece uma em um print compartilhado com um cliente.
Openverse Não Um catálogo com licenças abertas e API pública, mantido pela WordPress.org. Correspondência por palavra-chave, e as licenças variam por item — você precisa lê-las.

A distinção que importa: um placeholder é temporário por definição. Se a imagem sobrevive até a produção, ela deixa de ser um placeholder — vira uma ilustração que ninguém escolheu, e o leitor percebe.

Uma chave em vez de três

Aqui está a parte da migração que ninguém planeja: quem sai do Source raramente pousa em uma API só. Uma página precisa de um herói, duas imagens de seção e algo para uma grade de cards, e a resposta honesta costuma ser Unsplash mais Pexels mais Pixabay — três cadastros, três esquemas de autenticação, três formatos de JSON, três modelos de paginação e três conjuntos de regras de atribuição, tudo para preencher as mesmas tags <img>. Esse trabalho de integração é a conta real que se paga quando uma URL sem chave deixa de existir, e ela chega semanas depois da interrupção que a causou.

Reduzir isso a uma única integração é o motivo pelo qual construímos o Pexafy: uma única chave sobre 9 bibliotecas de licença gratuita em um único esquema, com busca semântica no nível de frase — de modo que uma descrição completa como “a cracked phone screen on a wooden desk, shot from above” retorne resultados classificados em vez de nada. Dois limites, ditos com clareza, porque este artigo inteiro é sobre não ser surpreendido duas vezes: ele precisa de uma chave, então não restaura o que o Source era — ele pertence à mesma categoria da API oficial da Unsplash mencionada acima; e carrega fotografia de licença gratuita, não imagens editoriais ou de marca.

A parte genuinamente nova é voltada para os assistentes mencionados acima: um servidor MCP em mcp.pexafy.com/mcp significa que um modelo que de outra forma recitaria uma URL de imagem de memória pode buscar em um catálogo real e retornar uma foto que existe, com sua linha de crédito anexada. Essa é uma resposta melhor para URLs mortas escritas por máquinas do que qualquer regra de lint, e o raciocínio está detalhado em infraestrutura de busca de imagens para agentes de IA.

Audite seu acervo em dez minutos

Para qualquer que seja o destino da sua migração, faça esta parte primeiro — você não consegue corrigir URLs que não encontrou. O Source é só o exemplo de hoje; os mesmos três passos se aplicam a todo recurso externo que você incorpora.

encontre toda referência morta e depois as mantenha fora
# 1. Tudo no repositório, incluindo docs, testes, fixtures e READMEs.
grep -rn --binary-files=without-match \
  -e "source.unsplash.com" -e "via.placeholder.com" -e "/placeholder.png" .

# 2. Tudo o que o banco de dados guarda — corpos de CMS são onde isso se esconde por mais tempo.
psql -c "SELECT id FROM posts WHERE body LIKE '%source.unsplash.com%'"

# 3. Tudo que o site já construído de fato requisita: rastreie e liste as falhas.
#    Combine com o atributo, não com uma extensão de arquivo — URLs de imagem raramente terminam em .jpg.
grep -rhoE 'src="[^"]+"' dist/ \
  | cut -d'"' -f2 | grep -E '^https?://' | sort -u \
  | xargs -P8 -I{} curl -s -o /dev/null -w "%{http_code} {}\n" {} \
  | grep -v "^200"

# 503 https://source.unsplash.com/random/1200x800   ← o que você está procurando

Depois decida, de uma vez por todas, quanto as imagens externas podem custar a você. Quatro regras que sobrevivem ao próximo desligamento, seja lá quem o causar:

  1. Busque no momento do build, não no momento da requisição. Uma imagem resolvida durante o build falha na CI, na frente de um desenvolvedor, em vez de às 3h da manhã na frente de um usuário.
  2. Nunca deixe um recurso decorativo bloquear um caminho crítico. Não pré-carregue nada externo acima de um formulário de login; dê a cada <img> de terceiros um fallback de onerror e um width/height explícitos, para que uma falha custe uma caixa em branco, não um deslocamento de layout ou um script travado.
  3. Adicione a verificação à CI. O passo 3 acima, executado na sua saída final, transforma um “alguém acabou notando” em um build vermelho. É o único passo que evita recorrência.
  4. Trate suas dependências externas com o mesmo orçamento que qualquer outra. Anote em quais hosts suas páginas têm permissão de depender e o que acontece quando cada um cai. Uma URL para a qual você não precisou se cadastrar ainda é uma dependência — o Source provou que é simplesmente uma que ninguém possui.

Referências e notas de rodapé

1 Todo código de status, contagem e trecho citado neste artigo foi obtido de sua fonte primária em 30 de agosto de 2026. Os códigos de status HTTP foram obtidos com curl contra cada padrão de URL; todos retornaram 503 com server: Heroku e um corpo incorporando herokucdn.com/error-pages/application-error.html. A resolução de DNS foi confirmada no mesmo dia (um CNAME para um host herokudns.com).

2 As duas entradas de changelog são citadas literalmente de unsplash.com/documentation/changelog. A redação da política de descontinuação (3 semanas de aviso, cabeçalho Warning, e a isenção para endpoints não publicamente documentados) vem de unsplash.com/documentation, no mesmo dia.

3 A falha de TLS foi reproduzida com openssl s_client -connect changelog.unsplash.com:443 (tlsv1 alert internal error). A cadeia de redirecionamento foi seguida com curl -L. A lacuna do arquivo foi obtida na API CDX do Wayback: última captura 200 de changelog.unsplash.com em 20240324, primeira de unsplash.com/documentation/changelog em 20240823.

4 Títulos das issues, datas de criação e fechamento lidos na API REST do GitHub (mui/material-ui#42736, nextcloud/unsplash#115, sindresorhus/Actions#248) e na API JSON do drupal.org para a issue 3324054 do gin_login, cujo corpo relata “I get always a Heroku application error” em novembro de 2022.

5 Contagens: API de busca de código do GitHub (3.344 arquivos; uma amostra de 100 resultados deduplicada para 77 repositórios, dos quais 12 foram criados depois de 11 de junho de 2024 e 20 tiveram commits nos 12 meses anteriores); API de downloads do registro npm (unsplash-source-es6, 23 downloads nos 30 dias anteriores); Stack Exchange /search/excerpts (1.459 posts). A busca de código cobre apenas repositórios públicos indexados, então cada número é um piso.

Perguntas frequentes

O source.unsplash.com está fora do ar ou foi desativado permanentemente?
Permanentemente. A Unsplash anunciou o encerramento em 11 de junho de 2024 — “primeiro vamos encerrar desativando o recurso de busca e, nas próximas semanas, desligar a aplicação por completo” — depois de já ter depreciado o serviço em 25 de novembro de 2021. Todo padrão (/random, /1600x900/?query, /collection/…, /daily) agora retorna HTTP 503 com a página genérica de Application Error do Heroku. O hostname ainda resolve, então a falha aparece como uma imagem quebrada em vez de um erro de rede.
Qual é o substituto direto do source.unsplash.com/random?
Não existe uma alternativa sem chave que sirva de substituição imediata, e essa é a parte que vale a pena aceitar logo de cara. Existem três alternativas. Uma URL fixa de CDN — images.unsplash.com/photo-…?w=1600&h=900&fit=crop — não precisa de chave, mas sempre retorna a mesma foto, o que na verdade já atende à maioria dos usos decorativos. A API oficial, GET https://api.unsplash.com/photos/random com um cabeçalho Authorization: Client-ID, restaura a aleatoriedade, mas precisa ser chamada no servidor. Um pequeno proxy próprio na frente desse endpoint é a única opção que devolve uma URL sem chave, pronta para ser colocada direto numa tag <img>.
Por que ferramentas de codificação com IA ainda geram URLs do source.unsplash.com em 2026?
Porque a URL foi documentada, ensinada e copiada por cerca de oito anos, e um corpus de treinamento não expira quando um serviço expira. Medido em 30 de agosto de 2026: a busca de código do GitHub ainda retorna 3.344 arquivos contendo a URL, e em uma amostra de 100 arquivos, 12 dos 77 repositórios foram criados depois do desligamento. Bibliotecas de prompts escritas por humanos também repetem a instrução — um prompt de GPT amplamente copiado ainda instrui o modelo a “usar a API do unsplash( https://source.unsplash.com/1280x720/?… )”. Trate qualquer URL de imagem gerada por um modelo como não verificada e confira os códigos de status no CI.
Ainda dá para pegar uma foto aleatória da Unsplash sem chave de API?
Não diretamente pela Unsplash — a seleção aleatória agora está por trás de /photos/random, que exige um Client-ID. Suas duas rotas sem chave são: um proxy que você mesmo hospeda, onde a chave fica no servidor e a URL pública se parece com a antiga, ou um serviço de placeholder de terceiros como o Lorem Picsum (picsum.photos/800/600), que oferece fotos reais sem chave, mas sem nenhum direcionamento por assunto.
A API da Unsplash permite baixar e hospedar as imagens no meu próprio servidor?
Não. Ao contrário da maioria das APIs, a Unsplash exige hotlinking: as URLs de imagem retornadas pela API precisam ser incorporadas diretamente, para que as visualizações da foto sejam contabilizadas para o fotógrafo. Três obrigações vêm junto — manter o parâmetro ixid ao redimensionar ou cortar a URL, dar crédito ao fotógrafo e à Unsplash, e disparar o endpoint de download da foto quando um usuário baixa o arquivo. Espelhar os arquivos na sua própria CDN é a única otimização que você não tem liberdade de fazer.
Por que o aviso de descontinuação de 2021 não protegeu os usuários existentes?
Porque o aviso e a política não cobriam a mesma coisa. A entrada do changelog de 25 de novembro de 2021 prometia que “os usos existentes continuarão funcionando” e não dava nenhuma data de encerramento. A política de descontinuação publicada pela Unsplash — pelo menos três semanas de aviso mais um cabeçalho Warning — se aplica a campos e endpoints publicamente documentados, e o mesmo parágrafo afirma que qualquer coisa não documentada pode mudar sem aviso prévio. O Source nunca foi um endpoint documentado da API, então ficou fora da política que o protegeria.
Como encontro todas as URLs mortas do source.unsplash.com no meu projeto?
Três passagens, dez minutos. Faça um grep no repositório incluindo docs, testes, fixtures e READMEs — grep -rn "source.unsplash.com" . — já que essas URLs sobrevivem por mais tempo em código de exemplo. Consulte o banco de dados, porque é onde elas se escondem nos corpos de artigos do CMS (WHERE body LIKE '%source.unsplash.com%'). Depois rastreie a saída compilada do seu projeto: extraia cada URL de imagem e faça uma requisição para cada uma, listando tudo que não retornar 200. Adicione essa última passagem ao CI, e um recurso de terceiro morto faz o build falhar em vez de quebrar uma página.

Pare de caçar palavras-chave. Descreva o que você quer dizer.

Busque 9M+ imagens gratuitas por significado — em qualquer idioma, em menos de 100 ms.