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:
curlandjq. 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-alignmentWhat happened
POST /v1/analysesuploaded the image. TheIdempotency-Keyheader makes a retry safe; see Idempotency. The API answered202with the analysisidstraight away.GET /v1/analyses/{id}returned the currentstatusuntil it wascompleted. Instead of polling you can use webhooks.- 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"
Use the real north angle in production
The examples send 0, which means north is at the top of the image. For a live analysis send the angle that matches your floor plan. See Review flows for what it means and when review steps happen.
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.