Quickstart

Submit a floor plan with a test key, wait for the result and print it. This takes about fifteen seconds in the sandbox.

Before you start

  • A test API key (gfy_test_...). Your organization owner or admin creates it; see Getting access.
  • A floor plan image saved as floor-plan.png (JPEG, PNG or WebP, up to 10 MB). In the sandbox any image gives the same sample result.
  • For curl: curl and jq. For Node.js: version 22 or later.

1. Submit, wait and read the result

The script submits the image, checks the analysis every five seconds, and prints the final status, score and band.

#!/usr/bin/env bash
# Requires curl and jq.
set -euo pipefail

API_BASE='https://api.grihafy.com/v1'
API_KEY='gfy_test_...'        # A test key from your organization settings. Keep it on your server.
FLOOR_PLAN='floor-plan.png'   # JPEG, PNG or WebP, up to 10 MB.

# Calls the API. Usage: api METHOD PATH [extra curl options]
api() {
  local method=$1 path=$2
  shift 2
  curl --fail-with-body -sS -X "$method" "$API_BASE$path" \
    -H "Authorization: Bearer $API_KEY" "$@"
}

# Prints the error body (it contains the error code and request ID) and stops.
fail() {
  echo "Request failed: $1" >&2
  exit 1
}

# 1. Submit the floor plan.
# The Idempotency-Key lets you retry this exact request safely: reuse the same value if you repeat it.
IDEMPOTENCY_KEY="$(uuidgen)"
analysis=$(api POST /analyses \
  -H "Idempotency-Key: $IDEMPOTENCY_KEY" \
  -F "file=@$FLOOR_PLAN" \
  -F 'reviewMode=auto' \
  -F 'northAngle=0') || fail "$analysis"
analysis_id=$(jq -r '.id' <<<"$analysis")
echo "Submitted analysis $analysis_id"

# 2. Check every 5 seconds until the analysis has finished.
while true; do
  analysis=$(api GET "/analyses/$analysis_id") || fail "$analysis"
  status=$(jq -r '.status' <<<"$analysis")
  echo "Status: $status"
  case "$status" in
    completed | failed | expired) break ;;
  esac
  sleep 5
done

# 3. Print the outcome.
jq '{status, score: .result.score, band: .result.band}' <<<"$analysis"

You should see output like this. The curl version prints the same values as JSON.

Submitted analysis 507f1f77bcf86cd799439011
Status: queued
Status: processing
Status: completed
completed 86 strong-alignment

What happened

  1. POST /v1/analyses uploaded the image. The Idempotency-Key header makes a retry safe; see Idempotency. The API answered 202 with the analysis id straight away.
  2. GET /v1/analyses/{id} returned the current status until it was completed. Instead of polling you can use webhooks.
  3. Because the script sent northAngle, no review step was needed. Test keys use no credits.

2. Try a review step

Sometimes an analysis pauses and waits for you. This version leaves out northAngle and asks Grihafy to pause when north is uncertain. When the status becomes review_required the script sends the north angle, and the analysis carries on.

#!/usr/bin/env bash
# Requires curl and jq.
set -euo pipefail

API_BASE='https://api.grihafy.com/v1'
API_KEY='gfy_test_...'        # A test key from your organization settings. Keep it on your server.
FLOOR_PLAN='floor-plan.png'   # JPEG, PNG or WebP, up to 10 MB.

# Calls the API. Usage: api METHOD PATH [extra curl options]
api() {
  local method=$1 path=$2
  shift 2
  curl --fail-with-body -sS -X "$method" "$API_BASE$path" \
    -H "Authorization: Bearer $API_KEY" "$@"
}

# Prints the error body (it contains the error code and request ID) and stops.
fail() {
  echo "Request failed: $1" >&2
  exit 1
}
NORTH_ANGLE=0   # Degrees clockwise from the top of the image to north. 0 means north is at the top.

# 1. Submit without a north angle and ask to be asked when north is uncertain.
IDEMPOTENCY_KEY="$(uuidgen)"
analysis=$(api POST /analyses \
  -H "Idempotency-Key: $IDEMPOTENCY_KEY" \
  -F "file=@$FLOOR_PLAN" \
  -F 'reviewMode=north_if_low_confidence') || fail "$analysis"
analysis_id=$(jq -r '.id' <<<"$analysis")
echo "Submitted analysis $analysis_id"

# 2. Check every 5 seconds. When the analysis needs the north angle, send it.
while true; do
  analysis=$(api GET "/analyses/$analysis_id") || fail "$analysis"
  status=$(jq -r '.status' <<<"$analysis")
  echo "Status: $status"
  case "$status" in
    completed | failed | expired) break ;;
    review_required)
      stage=$(jq -r '.review.stage' <<<"$analysis")
      if [ "$stage" != north ]; then
        fail "This analysis needs room review. See POST /analyses/{id}/rooms in the API reference."
      fi
      # The analysis goes back to "queued" and continues with your angle.
      api POST "/analyses/$analysis_id/north" \
        -H 'Content-Type: application/json' \
        -d "{\"northAngle\": $NORTH_ANGLE}" > /dev/null || fail "north review rejected"
      ;;
  esac
  sleep 5
done

# 3. Print the outcome.
jq '{status, score: .result.score, band: .result.band}' <<<"$analysis"

Next steps

  • Analyses: image rules, statuses, listing and deleting.
  • Webhooks: receive results without polling.
  • Going live: the checklist before you switch to a live key.