# What does google_calendar.event.guests_invited prove?

> Prove that the guests the person named are on the invitation. Version 1.0.0, certification Provisional.

Canonical: https://provely.sh/verify/google_calendar/google_calendar.event.guests_invited  
Last reviewed: 2026-09-05  
Skill version: 0.1.0  
Certification: provisional  

**Prove that the guests the person named are on the invitation. The stored attendee list holds the addresses that the person named. It does not prove that Google mailed a guest, or that a guest accepted.**

*Contract identity.*

| Fact | Value |
| --- | --- |
| Contract id | `google_calendar.event.guests_invited` |
| Version | `1.0.0` |
| Hash | `c196fc8c385fd780` |
| Completion level | `guests_invited` |
| Publisher | Built and signed by Provely. |
| Certification | Provisional |
| Skill | [Google Calendar API 0.1.0](/verify/google_calendar) |
| Valid for provider API versions | `v3.20260826` |

## What is the intent?

Put the meeting on the calendar and invite the named people.

## What is the subject and the action?

| Member | Value |
| --- | --- |
| Subject type | `google_calendar.event` |
| Subject identity | event_id = `$action.result.id` |
| Canonical effect | `calendar.event_create` |
| Provider operation | `POST /calendar/v3/calendars/{calendarId}/events` |
| Idempotency | none, retry is not safe |

## How does the evidence correlate with this operation?

| Strategy | Assurance | Keys | Required |
| --- | --- | --- | --- |
| `resource_id` | strong | event_id from `$action.result.id` | no |
| `resource_id` | weak | calendar_id from `$input.calendar_id` | no |
| `fingerprint` | weak | calendar_id from `$input.calendar_id`; summary from `$input.summary` | no |

## Which evidence does the contract require?

Minimum evidence level `E2`. An independent channel is required. Minimum channels: 1.

| Channel | Level | Independence | Verifier | Description |
| --- | --- | --- | --- | --- |
| `event_readback` | E2 | provider readback | `http` | Read the new event from the provider. A condition path is $observed.event_readback.start.dateTime. Google returns the instant in the time zone of the calendar, so a condition compares instants and never two strings. |
| `calendar_change_events` | E3 | provider event | `webhook` | The notifications of a channel that watches the events collection of the calendar, since the operation started. The webhook verifier returns {events, count, latest, earliest, types, duplicates_dropped}. The body is empty, so a count names no event. |

## Which conditions must all hold for VERIFIED?

| Condition | Meaning | Path | Operator | Expected | Evidence |
| --- | --- | --- | --- | --- | --- |
| `event_present` | The provider holds the event with the identifier of the insert answer. | `$observed.event_readback.id` | `eq` | `$action.result.id` | `event_readback` |
| `event_title_matches` | The title of the event equals the title that the person named. | `$observed.event_readback.summary` | `eq` | `$input.summary` | `event_readback` |
| `event_status_confirmed` | The status of the event is confirmed. The published description names that value the default status. | `$observed.event_readback.status` | `eq` | `confirmed` | `event_readback` |
| `event_starts_at_the_requested_instant` | The stored start names the instant that the person named. | — | `all_of` | The rows below state the members. | `event_readback` |
| `event_starts_at_the_requested_instant_not_before` | The stored instant is not before the instant that the person named. | `$observed.event_readback.start.dateTime` | `time_after` | `$input.start_time` | `event_readback` |
| `event_starts_at_the_requested_instant_not_after` | The stored instant is not after the instant that the person named. | `$observed.event_readback.start.dateTime` | `time_before` | `$input.start_time` | `event_readback` |
| `event_ends_at_the_requested_instant` | The stored end names the instant that the person named. | — | `all_of` | The rows below state the members. | `event_readback` |
| `event_ends_at_the_requested_instant_not_before` | The stored instant is not before the instant that the person named. | `$observed.event_readback.end.dateTime` | `time_after` | `$input.end_time` | `event_readback` |
| `event_ends_at_the_requested_instant_not_after` | The stored instant is not after the instant that the person named. | `$observed.event_readback.end.dateTime` | `time_before` | `$input.end_time` | `event_readback` |
| `event_created_in_window` | The provider created the event after the operation started. | `$observed.event_readback.created` | `time_after` | `$operation.created_at` | `event_readback` |
| `calendar_changed` | At least one notification says that the events collection of the calendar changed since the operation started. The published page states that a small percentage of messages drop, so a lost message leaves this level unproven and never verified. | `$observed.calendar_change_events.count` | `gte` | `1` | `calendar_change_events` |
| `every_requested_guest_is_an_attendee` | The stored attendee list holds the addresses that the person named. No published sentence states the order of the list, so a reorder leaves this level unproven and never verified. | `$observed.event_readback` | `jsonpath` | `$input.guest_emails` | `event_readback` |
| `attendee_count_matches` | The stored attendee list holds exactly as many entries as the person named. A stranger on the list therefore fails this condition. | `$observed.event_readback.attendees` | `array_length` | `$input.guest_count` | `event_readback` |

## Which conditions give CONTRADICTED?

| Condition | Class | Reason | Path | Operator | Expected |
| --- | --- | --- | --- | --- | --- |
| `event_title_differs` | wrong subject | The event carries a different title than the person named. | `$observed.event_readback.summary` | `ne` | `$input.summary` |
| `event_starts_too_early` | wrong subject | The event starts before the instant that the person named. | `$observed.event_readback.start.dateTime` | `time_before` | `$input.start_time` |
| `event_starts_too_late` | wrong subject | The event starts after the instant that the person named. | `$observed.event_readback.start.dateTime` | `time_after` | `$input.start_time` |
| `event_ends_too_early` | wrong subject | The event ends before the instant that the person named. | `$observed.event_readback.end.dateTime` | `time_before` | `$input.end_time` |
| `event_ends_too_late` | wrong subject | The event ends after the instant that the person named. | `$observed.event_readback.end.dateTime` | `time_after` | `$input.end_time` |
| `event_predates_operation` | pre existing state | The event is older than the operation. It proves nothing about this operation. | `$observed.event_readback.created` | `time_before` | `$operation.created_at` |
| `duplicate_calendar_change` | duplicate side effect | The calendar changed more than once since the operation started. A second insert mails every guest a second time. Do not retry. | `$observed.calendar_change_events.count` | `gt` | `1` |
| `attendee_list_truncated` | partial completion | The read returned a short attendee list. The verifier cannot see every guest. Ask a person. | `$observed.event_readback.attendeesOmitted` | `eq` | `true` |

## Which observed states map to a verdict before completion?

| Rule | Match | Verdict | Reason |
| --- | --- | --- | --- |
| `event_is_cancelled` | `$observed.event_readback.status` eq `"cancelled"` | CONTRADICTED | The event is cancelled. The published description states that a cancelled event is a deleted event. The API reports no failure for this end. |
| `event_is_a_locked_copy` | `$observed.event_readback.locked` eq `true` | CONTRADICTED | The event is a locked copy. The published description states that nobody can change its title, its start or its end. Ask a person. |
| `event_is_all_day` | `$observed.event_readback.start.date` exists `undefined` | CONTRADICTED | The agent created an all-day event. This level promises a timed event, and an all-day event carries no dateTime, so no later read can prove the instant. |
| `the_wrong_people_are_on_the_invitation` | (`$observed.event_readback.attendees` exists `undefined`) and (not (`$observed.event_readback` jsonpath `"$input.guest_emails"`)) | CONTRADICTED | The invitation names other people than the person asked for. A guest who should not see the meeting can see it, or a guest who should see it cannot. Ask a person. |

## How long does the runtime observe?

| Timing member | Value |
| --- | --- |
| Initial delay | 1000 ms |
| Poll interval | 5000 ms |
| Backoff | exponential factor 2, max 60000 ms |
| Maximum attempts | 40 |
| Timeout | 900000 ms |
| Stale read window | 20000 ms |
| On timeout | UNVERIFIABLE (`evidence_unavailable_before_timeout`), escalated to a person |

## Where do these rules come from?

- `google_calendar.openapi#/components/schemas/Event/properties/attendees`: [google_calendar.openapi](https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest), retrieved 2026-09-09
- `google_calendar.openapi#/components/schemas/EventAttendee/properties/email`: [google_calendar.openapi](https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest), retrieved 2026-09-09
- `google_calendar.docs.events#create-an-event-and-invite-guests/a-created-event-reaches-the-calendar-of-every-attendee`: [google_calendar.docs.events](https://developers.google.com/workspace/calendar/api/guides/create-events), retrieved 2026-09-09
- `google_calendar.docs.events#create-an-event-and-invite-guests/the-mail-is-a-separate-promise-and-sendupdates-decides-it`: [google_calendar.docs.events](https://developers.google.com/workspace/calendar/api/guides/create-events), retrieved 2026-09-09
- `google_calendar.openapi#/components/schemas/Event/properties/id`: [google_calendar.openapi](https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest), retrieved 2026-09-09
- `google_calendar.openapi#/paths/~1calendar~1v3~1calendars~1{calendarId}~1events~1{eventId}/get/responses/200`: [google_calendar.openapi](https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest), retrieved 2026-09-09
- `google_calendar.openapi#/components/schemas/Event/properties/summary`: [google_calendar.openapi](https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest), retrieved 2026-09-09
- `google_calendar.openapi#/paths/~1calendar~1v3~1calendars~1{calendarId}~1events/post/requestBody`: [google_calendar.openapi](https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest), retrieved 2026-09-09
- `google_calendar.openapi#/components/schemas/Event/properties/status`: [google_calendar.openapi](https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest), retrieved 2026-09-09
- `google_calendar.docs.times#events-times-and-the-change-of-a-time/the-status-of-an-event`: [google_calendar.docs.times](https://developers.google.com/workspace/calendar/api/concepts/events-calendars), retrieved 2026-09-09
- `google_calendar.openapi#/components/schemas/Event/properties/created`: [google_calendar.openapi](https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest), retrieved 2026-09-09
- `google_calendar.docs.times#events-times-and-the-change-of-a-time/the-two-times-that-calendar-publishes-about-an-event`: [google_calendar.docs.times](https://developers.google.com/workspace/calendar/api/concepts/events-calendars), retrieved 2026-09-09
- `google_calendar.events#/events/calendar.events.exists`: [google_calendar.events](https://developers.google.com/workspace/calendar/api/guides/push), retrieved 2026-09-09
- `google_calendar.docs.push#push-notifications/one-resource-state-covers-three-different-changes`: [google_calendar.docs.push](https://developers.google.com/workspace/calendar/api/guides/push), retrieved 2026-09-09
- `google_calendar.openapi#/paths/~1calendar~1v3~1calendars~1{calendarId}~1events~1watch/post`: [google_calendar.openapi](https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest), retrieved 2026-09-09
- `google_calendar.docs.push#push-notifications/what-the-page-refuses-to-promise`: [google_calendar.docs.push](https://developers.google.com/workspace/calendar/api/guides/push), retrieved 2026-09-09
- `google_calendar.docs.events#create-an-event-and-invite-guests/an-attendee-needs-an-address`: [google_calendar.docs.events](https://developers.google.com/workspace/calendar/api/guides/create-events), retrieved 2026-09-09
- `google_calendar.openapi#/components/schemas/EventAttendee`: [google_calendar.openapi](https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest), retrieved 2026-09-09

### Can google_calendar.event.guests_invited return VERIFIED from the action response alone?

No. The minimum evidence level is E2. The action response is E1. The completion conditions read `event_readback` and `calendar_change_events`.

### What happens after the timeout?

The verdict is UNVERIFIABLE with the reason `evidence_unavailable_before_timeout`. The operation goes to a person for review.

## Read next

- [Read the Google Calendar API verification page](https://provely.sh/verify/google_calendar)
- [Read the google_calendar.event.created contract](https://provely.sh/verify/google_calendar/google_calendar.event.created)
- [Read the google_calendar.event.rescheduled contract](https://provely.sh/verify/google_calendar/google_calendar.event.rescheduled)
- [Read what a completion contract contains](https://provely.sh/contracts)
- [Read what a receipt proves](https://provely.sh/docs/receipts)
