# HiRey: connect with someone from a photo taken together

> Read this when the owner sends a photo of themselves with someone and names that person. Needs sign-in and the owner's own live Page.

Step numbers in this page refer to the HiRey agent guide: step 4 is sign-in ([setup.md](https://hirey.ai/docs/agents/setup.md)), step 5 is the owner's Page ([page.md](https://hirey.ai/docs/agents/page.md)), step 6 is a photo with someone ([photo-with-someone.md](https://hirey.ai/docs/agents/photo-with-someone.md)), step 7 is the company and products ([company-and-products.md](https://hirey.ai/docs/agents/company-and-products.md)) and step 8 is posting ([posts.md](https://hirey.ai/docs/agents/posts.md)). Every call is `POST https://hi.hirey.ai/v1/capabilities/hi.workspace-workflows/call` with `Authorization: Bearer <api_key>` and a body `{"action":"<operation>","payload":{...}}`; over MCP, the same operation runs through `workspace_workflows` (action, payload and confirmation map one to one).

<a id="photo-with-someone"></a>
#### 6. You took a photo with someone on HiRey

When the owner sends a photo of themselves with someone and names that person, you can connect them on HiRey. The person is identified only because the owner names them: never use face recognition, never compare faces, and don't guess who is in the photo. Connect one named person per photo; if more people are in it, ask the owner which one to connect. The owner needs a public Page of their own first (step 5). The call shape is the same as in step 5.

1. `people.find` `{"query":"<the name the owner gave>"}`. Take the result that matches that name; you need its `person_id` and `slug`. If nobody matches, tell the owner; this step only connects someone already on HiRey.
2. Ask the owner once, showing the photo, who is named and their Page, for example "Publish this photo with <name> (https://hirey.ai/p/<slug>) on HiRey? It will be public, and when HiRey can, <name> will also get a private card of it so they can confirm." If several results could be that person, list their addresses in the same question and let the owner pick. If the owner says it is the wrong person, stop; nothing has been sent to HiRey yet. Only after the owner says yes, run 3 to 7. That one yes covers every call in 3 to 7, including the card in 6, because the question said so; don't ask again.
3. Upload the photo (an `image/*` file). `PUT /v1/media-assets` does not accept an API key; use these calls:
   - `media.upload.prepare` `{"idempotency_key":"...","intent":"evidence","original_filename":"photo.jpg","mime_type":"image/jpeg","size_bytes":<bytes>,"content_sha256":"<hex SHA-256 of the file>","title":"<short title>"}` returns `media_work_id`.
   - `agentic_media.upload.describe` `{"media_work_id":"..."}` returns `missing_parts`, each with `url`, `offset_bytes`, `length_bytes` and `required_headers`.
   - For each part, `PUT <url>` with the file's bytes from `offset_bytes` for `length_bytes` (parts are 1 MiB) and that part's `required_headers` (`content-type: application/octet-stream` and `x-hi-upload-capability`). Send no `Authorization` header on these PUTs.
   - `agentic_media.upload.complete` `{"media_work_id":"...","idempotency_key":"..."}` returns `source_asset_id` (`mas_...`), the uploaded photo.
4. `capture.record` `{"idempotency_key":"...","source_kind":"upload","beneficiary_kind":"connector_person","subject_person_id":"<person_id from 1>","subject_resolution":"public","media_asset_id":"<source_asset_id>","occurred_at":"<when the photo was taken, ISO 8601 with a timezone>"}` returns `moment_id`. If it refuses that person, stop and tell the owner. Never retry by creating a new Person (`subject_resolution` `new`, or a `target_name`) for someone `people.find` returned.
5. Publish the photo:
   - `media.create` `{"idempotency_key":"...","media_kind":"image","media_asset_id":"<source_asset_id>"}` returns `media_id` and `revision`.
   - `media.request_review` `{"idempotency_key":"...","media_id":"...","revision":<revision>}`.
   - `media.review_decide` `{"idempotency_key":"...","media_id":"...","revision":<revision>,"verdict":"approved"}` with `"confirmation":{"approved":true,"operation":"media.review_decide"}` returns `result_revision`.
   - `media.authorize` `{"idempotency_key":"...","media_id":"...","revision":<result_revision>}` with `"confirmation":{"approved":true,"operation":"media.authorize"}` returns `authorization_id`.
   - `capture.publish_photo_moment` `{"idempotency_key":"...","moment_id":"...","media_id":"...","authorization_id":"...","expected_media_asset_id":"<source_asset_id>","public_contexts":[]}` with `"confirmation":{"approved":true,"operation":"capture.publish_photo_moment"}`.
   - If any call in 3 to 5 refuses, tell the owner the photo was not published and stop. Don't make the card.
6. Only after `capture.publish_photo_moment` succeeds, make the card for that person to confirm: `meeting_share.invite` `{"idempotency_key":"...","moment_id":"<moment_id from 4>","media_asset_id":"<source_asset_id>","subject_person_id":"<person_id from 1>"}` with `"confirmation":{"approved":true,"operation":"meeting_share.invite"}`. It returns `share_id`, `recipient_url` (a private link to the card), `target_notified` and `not_notified_reason`. If it refuses, see 8.
7. Tell the owner the photo is published: within about a minute, a dashed line between the owner and that person appears on HiRey. Then:
   - `target_notified` is `true`: HiRey is letting that person know itself, with a link to the card. Its message is fixed text with no words from you or the owner; the card shows who sent it. It may wait until morning, and HiRey does not confirm delivery. Tell the owner HiRey is letting them know (it may wait until morning). Give the owner `recipient_url` only if they ask to send it themself too.
   - `target_notified` is `false`: HiRey sent nothing (`not_notified_reason` says why, for example HiRey can't reach them directly, or already told them about an earlier card). Give the owner `recipient_url` to text to that person from their own phone.
   - Either way, you never post the link or send it yourself: anyone who has it can see this card and photo. The person opens it, signs in and taps Connect, and the line turns solid. Connecting through the link works for 30 days.
   - Keep `moment_id`, `source_asset_id` and `share_id`. To make a new card later (the person has joined since, or 30 days have passed), when the owner asks, call only `meeting_share.invite` again with the same `moment_id` and `media_asset_id` and a new `idempotency_key`. Never upload the same photo again or repeat 3 to 5 for it. If you no longer have those ids, tell the owner instead. Keep `share_id` in case the owner wants to cancel the link (9).
8. If `meeting_share.invite` refuses (the photo stays published either way):
   - `subject_not_originated_here`: that person hasn't joined HiRey yet and someone else added them, so HiRey won't make a card for them. The photo stays published with a dashed line. Tell the owner the photo is up and nothing more is needed now; once that person joins HiRey, you can make the card if the owner asks (7).
   - `sender_display_name_required`: the owner has no name that others see on HiRey yet. If the owner has told you their own name, save it with `identity.update_display_name` `{"idempotency_key":"...","display_name":"<the name they gave>"}` (only their own profile changes) and tell them in a few words that this is the name others will see. Otherwise ask them what name to show; they can also add it at https://hirey.ai/me. Then call `meeting_share.invite` again with a new `idempotency_key`. Never replace a name the owner already has unless they ask you to.
   - `recipient_display_name_required`: the owner's own record of that person has no name. Save the name the owner gave with `person.display_name.set` `{"idempotency_key":"...","subject_person_id":"<person_id from 1>","display_name":"<that name>"}` (only the owner sees it), then call `meeting_share.invite` again with a new `idempotency_key`.
   - Anything else (for example `not_found`): tell the owner the card couldn't be made. The photo stays published with a dashed line. Don't retry with another person.
9. If the owner wants to cancel the link (for example it went to the wrong person): `meeting_share.revoke` `{"idempotency_key":"...","share_id":"<share_id from 6>"}` with `"confirmation":{"approved":true,"operation":"meeting_share.revoke"}`; the owner asking is the yes. The card, its photo and the link stop working at once, even if the link was already sent. The published photo stays. It returns `state` `revoked`, or `declined` if the person had already said Not me.
