Sanity Pioneers: Get early access to betas, extra AI credits, and a direct line to the engineering team. Apply now

How to populate inputs on a Sanity site via external API

3 repliesLast updated: Nov 29, 2025

Is it possible to populate input options from an external API? The use case is that we have artworks stored on our own server, and would like to feature certain ones to show on our website’s homepage.
AI Update

Yes, absolutely! You can populate input options from an external API in Sanity. Based on your use case of featuring artworks from your own server, you have a couple of approaches:

Custom Input Component Approach

The most flexible solution is to create a custom input component that fetches data from your external API. Here's how this would work:

import {useEffect, useState} from 'react'
import {set, unset} from 'sanity'
import {Stack, Card, Text, Button} from '@sanity/ui'

function ArtworkSelector(props) {
  const {value, onChange} = props
  const [artworks, setArtworks] = useState([])
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    // Fetch artworks from your external API
    fetch('https://your-server.com/api/artworks')
      .then(res => res.json())
      .then(data => {
        setArtworks(data)
        setLoading(false)
      })
  }, [])

  const handleSelect = (artwork) => {
    onChange(set(artwork))
  }

  if (loading) return <Text>Loading artworks...</Text>

  return (
    <Stack space={3}>
      {artworks.map(artwork => (
        <Card 
          key={artwork.id}
          padding={3}
          border
          selected={value?.id === artwork.id}
        >
          <Button onClick={() => handleSelect(artwork)}>
            {artwork.title}
          </Button>
        </Card>
      ))}
    </Stack>
  )
}

// In your schema
{
  name: 'featuredArtwork',
  type: 'object',
  components: {
    input: ArtworkSelector
  }
}

Dynamic Options with Lists

For simpler cases, you can also use the options.list property in your schema and populate it dynamically when the Studio loads:

// Fetch artworks once during schema setup
const artworks = await fetch('https://your-server.com/api/artworks')
  .then(res => res.json())

// In your schema
{
  name: 'featuredArtwork',
  type: 'string',
  options: {
    list: artworks.map(artwork => ({
      title: artwork.title,
      value: artwork.id
    }))
  }
}

Best Practices

For your specific use case, I'd recommend the custom input component approach because:

The custom input components documentation provides comprehensive guidance on implementing these components, including how to properly handle the onChange prop using Sanity's PatchEvent system for updating values in the Content Lake.

Show original thread
3 replies

Was this answer helpful?

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Related contributions