Documentation

Build your first survey in minutes

Everything you need to prepare, publish, and share a SuAVE survey — from CSV formatting to Jupyter notebook integration.

Start here

What is SuAVE?

SuAVE (Survey Analysis via Visual Exploration) is a free web platform that turns a CSV file into an interactive, multi-view data explorer for images, maps, charts, and networks. Upload your data, add qualifiers where needed, and SuAVE renders a zoomable grid of image tiles linked to a faceted filter panel — no installation, no code, no database configuration. The platform is hosted at suave.sdsc.edu and is free for academic and non-commercial use.

The open-source SuAVE 2026 frontend (React 18 + Vite) can also be self-hosted and loaded with any CSV directly from the browser or via URL parameters — no account required for local exploration.

The five-minute workflow

  1. Prepare a CSV where each row is one survey item (respondent, specimen, artwork, location, …)
  2. Annotate column names with #number, #multi, #date, etc. to control how they appear
  3. If you have images, add them to the survey via the New Survey dialog (see Images section)
  4. Log in at suave.sdsc.edu, click New Survey, and upload the CSV
  5. Share the resulting URL — anyone with it can explore your data without an account
💡

SuAVE works best with 50–50,000 rows. Very small datasets (under 20 items) have limited visual value; very large ones (100,000+) may require server-side pagination — contact us for large-data deployments.

Additional resources

The full reference documentation is at suave-ucsd.github.io/SuAVE-Documentation, covering account setup, image galleries, LimeSurvey integration, bibliographic networks, Jupyter notebooks, and self-hosting. Video tutorials are on the SuAVE YouTube channel.

CSV format

SuAVE reads standard comma-separated values. The first row is the header — it defines ordinary variable names, reserved variable names, and optional qualifier suffixes (see next section). Values can be text, numbers, dates, pipe-separated lists, or URLs.

Minimal example

# Every row is one survey item. Columns can be in any order. #name, Species#multi, Period#number, #img, Notes#long, Latitude#number#hidden, Longitude#number#hidden "Ammonite A", "Cephalopoda|Mollusca", 145, "amm001", "Well-preserved suture lines", 51.5, -0.12 "Belemnite B", "Cephalopoda", 160, "bel002", "", 52.1, 0.34

Rules

For an ordinary variable, the display label is the part before the first #; any following tokens are qualifiers. A column named Geological Period#number#hidden has the label "Geological Period", is treated as a numeric range slider, and is hidden from the filter panel (but shown in the item detail panel). Reserved variable names such as #name are the exception: the entire header is the variable name.

Values in #multi columns are pipe-separated: Cephalopoda|Mollusca|Marine. Each pipe-delimited token becomes an independent checkbox in the filter panel.

UTF-8 encoding is required. Quote fields that contain commas. Empty cells are treated as missing values and displayed as "N/A" in the filter panel.

Loading options

Beyond direct upload, SuAVE 2026 accepts data from several sources via URL parameters. A Google Sheets share link (the /edit or /view form) is automatically converted to its CSV export equivalent. Any publicly accessible CSV can be loaded with ?csv_url=URL. A survey config JSON file can bundle the CSV URL, DZC URL, and view settings into a single shareable document (see Survey config files).

Variable naming and qualifier conventions

SuAVE CSV headers use three distinct conventions: exact reserved variable names, reserved words in spatial variable labels, and qualifiers appended to ordinary variable names. These conventions are not interchangeable.

Reserved variable names

The following are complete, exact column names. They begin with #, but they are variables—not qualifiers to append to another label.

Variable name Purpose Value in each row
#nameItem display name and detail-panel titlePlain text
#imgPrimary image identifierImage ID matching the survey's DZI/DZC data
#hrefMakes the #name title clickableItem-level URL
#netvisAssociates the item with network-visualization dataNetwork-data reference used by the Netvis view

#uniqueid and #views are legacy/internal headers recognized by the original SuAVE loader. Do not add them to new SuAVE 2026 CSV files: row IDs are generated automatically, and enabled views are configured in the survey settings.

ℹ️

Use these exact headers in new CSV files: #name, #img, and #href—not Name#name, Image#img, or Website#href. SuAVE 2026 accepts some labeled forms for compatibility, but the canonical SuAVE convention and the original implementation use exact reserved variable names.

Reserved spatial label words

Map columns are identified from the variable's label (the part before the first #), case-insensitively. They are not selected by #lat, #lon, or #coord qualifiers.

Label must contain Purpose Recommended header
LatitudePoint latitudeLatitude#number#hidden
LongitudePoint longitudeLongitude#number#hidden
GeometryWKT or GeoJSON geometry for points, lines, or polygonsGeometry#hiddenmore

Column qualifiers

Qualifiers are suffixes appended to an ordinary variable name with #. They control the data type, filtering, sorting, and visibility. Multiple compatible qualifiers can be chained, as in Depth#number#hidden.

Qualifier Filter panel Detail panel Notes
(none)Checkbox listDefault for text columns
#numberRange slider + histogramValues must be numeric
#dateDate range pickerISO 8601 or MM/DD/YYYY
#multiCheckbox listPipe-separated values; each token is a separate facet
#longSearch scope onlyLong text — appears in search scope dropdown, not as checkboxes
#linkClickable URLDisplayed as a hyperlink in the detail panel
#hiddenHidden from filter panel, visible in detail panel
#hiddenmoreHidden everywhere — useful for internal IDs
#infoBody textLong description rendered as prose in the detail panel
#ordinalOrdered categoriesCategories whose values have a natural order; numeric-prefixed values are ordered numerically
#sortquanCheckbox listSorts category values by item count instead of alphabetically by default
#textlocationLegacy address-geocoding qualifier; unsupported—use Latitude and Longitude columns instead
ℹ️

The 2026 parser recognizes #image, #lat, #lon, and #coord as compatibility type tokens. They are not canonical authoring conventions. In particular, #lat, #lon, and #coord do not make a column spatial: map detection still requires Latitude, Longitude, or Geometry in the label.

Images & DZI tiles

How images are specified in the #img column depends on which version of SuAVE you are using. The short answer to "can I just paste in a JPEG URL?" is: yes on the hosted platform, no in SuAVE 2026.

Hosted platform (suave.sdsc.edu)

The hosted platform supports two image delivery modes. When you upload images through the New Survey dialog, the server processes them into Deep Zoom Image (DZI) pyramids server-side. Your #img column values are then the bare filenames without extension — these are image IDs that the server resolves to the right DZI tile at every zoom level.

For surveys where items already have publicly accessible image URLs (JPEG, PNG), you can also paste those URLs directly into the #img column. The platform will display them at the resolution provided. This works well for moderate-size collections where deep zoom into individual images is not needed.

ℹ️

Images are uploaded through the New Survey dialog — not through a separate tool. When creating or editing a survey at suave.sdsc.edu, the survey settings dialog lets you specify which image files to include. The server processes them into DZI pyramids automatically. There is no longer a separate image upload step via an external service.

SuAVE 2026 (self-hosted / open source)

SuAVE 2026 requires DZI pyramids for all image display. The #img column values must be image IDs, not full URLs. At load time the viewer fetches a DZC manifest file that maps each image ID to its tile location. There is no direct-URL fallback: if no DZC is configured, items without resolved tiles render as colored placeholder shapes.

# Example: #img column values for DZI delivery # The DZC URL is set on the survey (server-side or in a config file), not per-row. # Per-row values are the image IDs — bare filename stems matching the uploaded files. Image#img fossil_001 fossil_002 fossil_003

Image format and tile resolution

The DZI format (PNG or JPEG) is read from the DZC XML's Format attribute — SuAVE never hardcodes it, so mixed-format collections work correctly. At high zoom levels in Grid view, SuAVE stitches multiple DZI tiles for seamless full-resolution display. The tile level formula is min(imgMaxLevel, ceil(log2(renderSize))), with no artificial cap.

Sprite sheets (instant low-res preview)

When you upload images through SuAVE 2026's New Survey dialog, a small composite sprite sheet is generated alongside the DZI pyramid for each survey — a grid of tiny, aspect-preserved thumbnails across a few low zoom levels. The viewer loads this one small file first, so items show a real (if low-resolution) preview immediately, before the full-resolution tiles finish loading — rather than staying blank or tile-by-tile. Surveys migrated in from elsewhere with only a DZI pyramid and no sprite sheet fall back to loading tiles directly; there's no visual difference once tiles finish loading, just a slower initial appearance.

Spatial columns

SuAVE detects spatial columns by label (the part before #), not by position. The label must contain the word "latitude", "longitude", or "geometry" (case-insensitive).

Point maps (lat/lon)

Name your columns so the label contains "latitude" and "longitude" — for example Latitude#number#hidden and Longitude#number#hidden. Adding #hidden keeps them out of the filter panel while still enabling the map. Coincident points (identical lat/lon) are automatically clustered at low zoom and spread at high zoom.

Geometry maps (WKT / GeoJSON)

A column whose label contains "geometry" is treated as a WKT or GeoJSON geometry column. SuAVE renders polygons, lines, and multipolygon features on the map. The #hidden suffix is recommended to keep the raw WKT out of the filter panel.

💡

A column named country_lat#number#hidden has the label country_lat, which does not contain "latitude" and will not be detected as a spatial column. Spell out the full word.

Publishing a survey

  1. Create an account at suave.sdsc.edu
  2. Click New Survey in your personal gallery
  3. Browse to your CSV file, assign a survey name, and submit
  4. If your survey includes images, select the image files in the same dialog — the server processes them into DZI tiles automatically
  5. Open Edit → Settings to choose which views to enable, set the default view, assign icon shapes and colors by variable, and designate the title field
  6. On the Edit Variables tab, add or adjust qualifiers (#long, #hidden, #number, etc.) without editing the CSV manually
  7. On the Describe Survey tab, fill in the data source, contact, and access date — this populates the survey's About page
  8. Set access control (public, link-only, or password-protected) and click Publish — your survey URL is immediately shareable

Updating a published survey

Upload a new CSV through the Edit dialog to replace the data while preserving all settings. If you add new image files, include them in the same upload step so the server can extend the DZI collection without regenerating existing tiles.

Cloning a public survey

Any public survey can be cloned into your account from the gallery. This creates a private copy with its own URL that you can modify — useful for extending an existing dataset or using a survey as a teaching template.

Loading a CSV without an account

SuAVE 2026 can open any CSV directly from the browser landing page — drag and drop, or paste a URL (Google Sheets links are converted automatically). No account required for local exploration. Note that image tiles require a configured DZC URL, so icon-based or text-only surveys work fully offline; image galleries need a backend.

Sample datasets

The SuAVE team maintains a curated set of sample datasets for workshops and experimentation, covering three broad types.

Surveys without images

These use icon specifications (shape and color driven by variable values) rather than photographs. The EarthCube Member Survey and various NSF award databases fall into this category. They are the simplest starting point: prepare a CSV, annotate the columns, upload — done.

Collections with limited icon sets

Surveys like the Observing Systems Explorer and 2018 SDG Indicators dataset use small, bounded image sets that are easy to process. Good for learning the image upload workflow without managing thousands of files.

High-resolution image collections

Examples include the Picasso Paintings survey, the USGS Earth As Art collection, the Van Gogh paintings collection, BGS Macrofossils, and wetland soil samples. These demonstrate the full DZI tile pipeline and deep-zoom interaction.

📂

A full list of sample datasets with direct links is maintained in the SuAVE sample datasets document. Each entry includes the CSV, any associated DZC URL, and a README explaining the data source. Published examples can be browsed at the 100+ Surveys page.

Practice with live data

A good first exercise: go to the NSF Awards search, run any keyword search, export the results as CSV, add a #number qualifier to the Amount column and a #date qualifier to the start date, then upload. You get a funded-project browser with a histogram and date filter in under ten minutes, no images required.

Available views

All views respond to the same filter state. Switch between them at any time — the set of visible items is always identical. Only views enabled for a given survey appear in the tab row.

Grid

The default view. Items appear as a scrollable, zoomable grid of tiles. Mouse wheel zooms continuously, anchored to the cursor position. Click any tile to open the detail panel. At high zoom levels SuAVE stitches multiple DZI tiles for full-resolution display. Tile name labels (from the #name column) can be toggled under Settings.

Bucket

Items sorted into vertical columns by the value of a chosen variable. Each column is a scrollable stack of tiles. Four group modes: Alphabetical ranges (default), Alphabetical individual, Natural order (when the data has a recognized sequence like Low / Medium / High), and Largest first. Effective for comparing visual character across categories.

Bars

Similar to Bucket but horizontal: items appear as rows of tiles grouped by a variable. Suited for comparing category sizes at a glance. For numeric variables, bar ranges use logarithmic bin widths with K/M/B abbreviations.

Crosstab

A two-dimensional grid of tiles defined by two chosen variables — one for rows, one for columns. Each cell shows the tiles for items matching both values. Counts appear in the cell headers.

Map

Available when the CSV has latitude/longitude or geometry columns. Points are clustered automatically at low zoom. Color markers by any categorical or numeric variable using categorical palettes or continuous colormaps (Cool-Warm, Viridis, Plasma, Inferno) with Equal, Quantile, or Jenks classification. WKT/GeoJSON polygon columns render as choropleth layers. Google My Maps KML overlays are supported via the map_overlay_link survey config field.

Table

A virtualized, sortable spreadsheet. Click any column header to sort ascending or descending. Handles very large datasets efficiently by rendering only visible rows.

List

A compact vertically scrollable list. Each row shows the item thumbnail, name, and a brief summary of key field values.

Heatmap

A color matrix cross-tabulating two categorical variables. Cell values show item counts or percentages (normalize by row, column, or none). Tooltip on hover. Export as PNG.

Scatter

Two-axis scatter plot. Select X axis, Y axis, an optional categorical color variable, and an optional numeric size variable. Export as PNG.

Timeline

Stacked bar chart of item counts over time. Granularity (decade, year, month) is chosen automatically from the data span. Click any bar to add a datetime filter for that period. Export as PNG.

Parallel coordinates

Each filtered item is a polyline crossing parallel numeric axes. Drag on any axis to brush-select a range; lines outside the brush are dimmed. Up to four axes pre-selected on first load. Export as PNG.

Sankey

A flow diagram between two categorical variables. Link width encodes item count. Click any link or node to filter. Export as PNG.

Network

A Cytoscape.js force-directed graph. Three dropdowns define the graph: Connect (source values become nodes), To (target values), and With (the linking variable). Co-occurrence mode: set Connect and To to the same field. Clicking a node applies a filter for that value.

Filtering & search

The filter panel lists every facet column as a collapsible accordion. Checking or unchecking values updates all views in real time — no page reload. Multiple selections within one facet combine as OR; selections across different facets combine as AND.

Search

The toolbar search box searches across all columns by default. When a #long column is selected in the scope dropdown, search narrows to that field. Within each facet accordion, a separate "Filter values…" input filters the checkbox list display — it does not affect item counts.

Advanced search

The search icon in the toolbar opens the multi-condition filter builder. Combine up to five conditions with AND or OR logic across any columns, using operators including contains, equals, starts with, and is empty.

Filter breadcrumbs

A row of colored chips below the toolbar summarizes all active filters. Click × on any chip to remove that filter. A Clear All button in the filter panel header removes everything at once.

Annotation mode

The annotation icon saves the current filter state — every active checkbox, range, and search term — as a named pattern in the browser's localStorage. Restore any saved pattern with a single click. Useful for teaching, where students document their analytical steps.

Sharing & export

Share link

The share icon in the toolbar encodes the complete current state (active filters, current view, zoom level, map position) into the URL and copies it to the clipboard. The recipient opens the link and sees exactly what you saw.

Download filtered CSV

The download icon exports the currently visible items as a CSV file — only rows that pass all active filters are included. Reserved variable names and qualifiers are preserved in the header.

Chart export

For chart views (Heatmap, Scatter, Timeline, Parallel, Sankey), a camera icon in the toolbar downloads the current chart as a high-resolution PNG.

Survey config files

A survey config file is a plain JSON document that bundles all the information needed to open a survey without a backend account. It is useful for self-hosted deployments, for sharing a survey with a specific pre-selected view or overlay, or for attaching Streamlit apps to a CSV that lives on an external URL.

// Example survey config file (save as mysurvey.json) { "csv": "https://example.com/data.csv", "dzc": "https://example.com/tiles/content.dzc", "fullname": "My Survey Title", "views": ["grid", "bucket", "bars", "map", "table"], "map_overlay_link": "https://www.google.com/maps/d/...", "show_image_labels": "always", "preamble": "<p>Welcome to this survey.</p>" }

Only csv is required. All other fields are optional. Load a config file with the URL parameter ?surveyconfig=URL. Google Sheets share links in the csv field are automatically converted to their export equivalent.

URL parameters

SuAVE 2026 accepts several URL parameters for opening a specific survey directly.

ParameterPurposeExample
?survey=filename.csvLoad a CSV from the server's surveys directory?survey=suavelocal_BGS_Macrofossils.csv
?user=X&file=YOriginal SuAVE URL style; equivalent to ?survey=X_Y.csv?user=suavelocal&file=BGS_Macrofossils
?csv_url=URLLoad any CSV from an arbitrary public URL?csv_url=https://…/data.csv
?surveyconfig=URLLoad a JSON config file (CSV + DZC + views + metadata)?surveyconfig=/configs/my.json
?skip_preamble=trueSuppress the intro modal on surveys that have one

Jupyter & Streamlit integration

SuAVE includes a bidirectional bridge to Jupyter notebooks and Streamlit apps. When enabled for a survey, buttons for these tools appear alongside the view tabs. Clicking either opens a dialog to select a server and launch the app with the current survey and filter context passed as URL parameters.

Python client

The suave_api Python package queries the currently filtered items from a running SuAVE session and returns them as a pandas DataFrame. It communicates with the SuAVE REST API (see REST API), which applies the same filter logic as the browser.

from suave_api import SuaveAPI # Notebook receives api_base and state from its own URL params # (set automatically by the Jupyter launch dialog) api_base = "http://localhost:5173/api/v1" state = "eyJ2aWV3IjoiZ3JpZCIs..." # from ?state= in the viewer URL api = SuaveAPI(api_base) df = api.items("suavelocal_BGS_Macrofossils", state=state) # df contains exactly the rows currently visible in the viewer print(f"{len(df)} items, columns: {list(df.columns)}") # Run your analysis, then push derived columns back df['cluster_label#hiddenmore'] = my_clustering(df) api.push_columns("suavelocal_BGS_Macrofossils", df[['cluster_label#hiddenmore']])

Streamlit apps

The survey's authoring panel lets you attach one or more Streamlit app URLs to a survey. Users launch them from within SuAVE — the app receives the current filter state, CSV URL, and DZC URL as query parameters and can render statistical summaries, ML results, or custom visualizations that update as the user filters.

Publishing a new survey from a notebook or Streamlit app

On self-hosted SuAVE 2026 deployments, creating a survey from a notebook or Streamlit app requires signing in with a real SuAVE account — this proves who's actually publishing, rather than trusting a plain username with no password. In practice this is a one-time prompt per session, not per operation:

  • Jupyter notebooks — the first call to create_survey(...) in a notebook run prompts for your SuAVE username, then your password (entered via getpass, so it's never echoed into saved notebook output). The resulting session is cached for the rest of that kernel run, so later calls in the same notebook don't prompt again.
  • Streamlit apps that publish back to SuAVE already ask for your SuAVE login and password in their own UI before uploading — nothing changes there from the user's side.

Notebooks and Streamlit apps that only read filtered data via suave_api (see REST API below) are unaffected — this only applies to creating or modifying a survey.

Notebook types

Several notebook templates are available for common workflows: bibliographic network analysis, image feature extraction, clustering, and geospatial analysis. The full list and instructions for adding custom notebooks are in the notebook types guide.

Survey integrations

SuAVE connects directly to KoboToolbox and LimeSurvey through their REST APIs. Once configured, new survey submissions flow into SuAVE automatically — no CSV exports, no scheduled imports, no reformatting.

KoboToolbox

KoboToolbox is the standard tool for humanitarian and field research surveys. It supports GPS location capture, photo uploads, offline data collection, and branching logic — making it the right choice for ecology surveys, archaeological fieldwork, urban assessments, and any study where respondents are not at a desk.

The integration uses KoboToolbox's REST service feature. To connect a Kobo form to SuAVE:

  1. In your KoboToolbox account, open the form you want to connect. Go to Settings → REST Services → Add Service.
  2. Set the endpoint URL to your SuAVE instance's Kobo ingest endpoint: https://suave.sdsc.edu/kobo/submit?user=YOUR_USERNAME&file=YOUR_SURVEY.csv
  3. Add your SuAVE API key in the Authorization header field.
  4. Save. From this point, every new Kobo submission triggers a POST to SuAVE, which appends the row and refreshes connected viewers.
📱

GPS and images map automatically. Kobo geopoint fields are split into columns whose names contain Latitude and Longitude, so map view activates without additional qualifiers. Photo fields populate the reserved #img variable, which supplies the image grid.

LimeSurvey

LimeSurvey is widely used for course-integrated research and institutional questionnaires. The SuAVE–LimeSurvey bridge uses LimeSurvey's RemoteControl API to pull responses on a configurable schedule (or on demand from the SuAVE authoring panel).

  1. In LimeSurvey, enable the RemoteControl 2 API under Global Settings → Interfaces and create an API user.
  2. In SuAVE's survey authoring panel, open the Data Source tab and choose LimeSurvey. Enter your LimeSurvey URL, API username, API password, and the survey ID.
  3. Choose a sync interval (5 minutes, hourly, or manual). SuAVE will poll for new responses and append them to the collection.
  4. Map LimeSurvey question codes to SuAVE column names and annotation qualifiers (e.g., append #number to numeric question codes).
📋

Live classroom use. A common pattern: students fill out a LimeSurvey form during class; the instructor projects SuAVE in the same room. Responses appear within minutes — the class watches the dataset grow and can start filtering before the survey closes.

Column mapping

Both integrations support a column mapping configuration that lets you rename fields and attach SuAVE annotation qualifiers at import time. A mapping file for a typical field survey looks like this:

# kobo_mapping.yaml field_latitude: "Latitude#number#hidden" field_longitude: "Longitude#number#hidden" field_photo: "#img" species_name: "Species" count: "Count#number" observer_notes: "Notes#long" habitat_type: "Habitat"

After mapping, SuAVE automatically enables map view (from the GPS column), image grid (from the photo column), range slider for Count, and long-text search for Notes — all without any manual column editing.

Teaching with SuAVE

SuAVE was designed in parallel with an undergraduate research methods curriculum at UCSD. Several design decisions specifically serve classroom use.

No installation. Students open a URL in any browser — no Python, no R, no data tools to install. Real survey data on day one. Loading the General Social Survey or an archaeological collection takes seconds; students start exploring before the lecture is over. Annotation as homework. The annotation feature lets students document their analytical narrative — filter state plus comment — and submit the URL as an assignment. Live LimeSurvey integration. Students fill out a form; their responses appear as new rows in SuAVE within minutes. The class can watch the dataset grow in real time. Graduated complexity. Beginners use the grid and bars; advanced students connect to Jupyter notebooks. The same interface supports both.

📋

A two-page quick-start handout for students is available on request. Email izaslavsky@ucsd.edu.

REST API

The SuAVE API runs on port 3004 (proxied through the viewer at /api/v1) and provides programmatic read access to survey data. It applies the same filter logic as the browser, so a notebook can receive the ?state= URL parameter from the viewer and query exactly the rows currently on screen.

# List all surveys in the server's surveys directory GET /api/v1/surveys # Survey metadata: facets, item count, enabled views GET /api/v1/surveys/{id} # Filtered items — pass state= from the viewer URL, or individual filter params GET /api/v1/surveys/{id}/items?state={base64state}&limit=5000 # Same endpoint, JSON body for complex filters from Python POST /api/v1/surveys/{id}/items Content-Type: application/json { "filters": { "stringFilters": { "Phylum": ["Mollusca", "Brachiopoda"] }, "numFilters": { "Age#number": { "min": 50, "max": 100 } } }, "limit": 1000, "fields": ["Phylum", "Age#number", "Locality"] } # Value distribution for one facet within a filtered subset GET /api/v1/surveys/{id}/facets/{facetName}?state={base64state} # Health check GET /api/v1/health → {"status":"ok","port":3004}

The `:id` segment is the CSV filename without the .csv extension, e.g. suavelocal_BGS_Macrofossils. Items responses include total count, filtered count, pagination offset, and an items array. Format can be JSON (default) or CSV (?format=csv or Accept: text/csv).

The API is part of the suave-api.tar.gz deployment bundle. The full endpoint reference, the Python helper class, and a step-by-step CentOS/RHEL deployment guide (nginx and Apache2 variants) are in DEPLOY.md, distributed with the source on GitHub.

Replace a single image

The authoring backend (port 3003) exposes one endpoint for updating an individual item's image without reprocessing the whole collection:

POST /manage/api/surveys/{id}/replace-image Authorization: Bearer {token} Content-Type: multipart/form-data image_id = fossil_042 # current value in the #img column new_image_id = fossil_042_hires # optional — rename in DZC + CSV image = <file> # JPEG/PNG/WebP, max 50 MB → {"ok":true,"image_id":"fossil_042_hires","w":2400,"h":1800,"csv_rows_updated":1}

The endpoint regenerates the full DZI pyramid, patches the DZC manifest in place, and (when new_image_id is supplied) updates every matching value in the survey's #img column. Other items and their tiles are never touched. Authentication requires the same Bearer token or session cookie as the survey management interface — the caller must own the survey.

Self-hosting

The complete SuAVE stack consists of four deployment bundles: the minified front-end (suave2026-dist.tar.gz), the unminified debug front-end (suave2026-dist-debug.tar.gz), the authoring backend (suave2026-backend.tar.gz), and the REST API (suave-api.tar.gz). A fifth bundle (suave-web.tar.gz) contains this website. Deploy order: authoring backend on port 3003, API on port 3004, then serve the static front-end from nginx or Apache2 with proxy rules for those two ports. Full instructions, nginx and Apache2 config templates, PM2 startup, and firewall/SELinux notes are in DEPLOY.md.