CINXE.COM

amphtml/extensions/amp-a4a/rtc-documentation.md at main · ampproject/amphtml · GitHub

<!DOCTYPE html> <html lang="en" data-color-mode="auto" data-light-theme="light" data-dark-theme="dark" data-a11y-animated-images="system" data-a11y-link-underlines="true" > <head> <meta charset="utf-8"> <link rel="dns-prefetch" href="https://github.githubassets.com"> <link rel="dns-prefetch" href="https://avatars.githubusercontent.com"> <link rel="dns-prefetch" href="https://github-cloud.s3.amazonaws.com"> <link rel="dns-prefetch" href="https://user-images.githubusercontent.com/"> <link rel="preconnect" href="https://github.githubassets.com" crossorigin> <link rel="preconnect" href="https://avatars.githubusercontent.com"> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/light-7aa84bb7e11e.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/dark-f65db3e8d171.css" /><link data-color-theme="dark_dimmed" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_dimmed-a8258e3c6dda.css" /><link data-color-theme="dark_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_high_contrast-7e97d834719c.css" /><link data-color-theme="dark_colorblind" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_colorblind-01d869f460be.css" /><link data-color-theme="light_colorblind" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_colorblind-534f3e971240.css" /><link data-color-theme="light_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_high_contrast-a8cc7d138001.css" /><link data-color-theme="light_tritanopia" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_tritanopia-35e9dfdc4f9f.css" /><link data-color-theme="dark_tritanopia" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_tritanopia-cf4cc5f62dfe.css" /> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-primitives-d9abecd14f1e.css" /> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-93aded0ee8a1.css" /> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/global-8bed0685a4b5.css" /> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/github-15d4b28ab680.css" /> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/repository-4fce88777fa8.css" /> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/code-0210be90f4d3.css" /> <script type="application/json" id="client-env">{"locale":"en","featureFlags":["a11y_quote_reply_fix","copilot_immersive_file_preview","copilot_new_references_ui","copilot_personal_instructions","copilot_personal_instructions_templates","copilot_chat_repo_custom_instructions_preview","copilot_chat_immersive_subthreading","copilot_chat_retry_on_error","copilot_chat_persist_submitted_input","copilot_conversational_ux_history_refs","copilot_chat_shared_chat_input","copilot_editor_upsells","copilot_implicit_context","copilot_no_floating_button","copilot_smell_icebreaker_ux","copilot_read_shared_conversation","dotcom_chat_client_side_skills","experimentation_azure_variant_endpoint","failbot_handle_non_errors","geojson_azure_maps","ghost_pilot_confidence_truncation_25","ghost_pilot_confidence_truncation_40","github_models_o3_mini_streaming","hide_billing_usage_filters","hovercard_accessibility","insert_before_patch","issues_advanced_search_custom_queries","issues_react_remove_placeholders","issues_react_blur_item_picker_on_close","issues_react_include_bots_in_pickers","marketing_pages_search_explore_provider","remove_child_patch","sample_network_conn_type","swp_enterprise_contact_form","site_copilot_extensions_ga","site_copilot_extensions_hero","site_copilot_vscode_link_update","site_proxima_australia_update","issues_react_create_milestone","issues_react_cache_fix_workaround","lifecycle_label_name_updates"]}</script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/wp-runtime-b73f4ebc2b59.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_oddbird_popover-polyfill_dist_popover_js-9da652f58479.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_arianotify-polyfill_ariaNotify-polyfill_js-node_modules_github_mi-3abb8f-d7e6bc799724.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_failbot_failbot_ts-4600dbf2d60a.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/environment-f04cb2a9fc8c.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_primer_behaviors_dist_esm_index_mjs-0dbb79f97f8f.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_selector-observer_dist_index_esm_js-f690fd9ae3d5.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_relative-time-element_dist_index_js-f6da4b3fa34c.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_auto-complete-element_dist_index_js-node_modules_github_catalyst_-8e9f78-a74b4e0a8a6b.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_text-expander-element_dist_index_js-78748950cb0c.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_filter-input-element_dist_index_js-node_modules_github_remote-inp-b5f1d7-a1760ffda83d.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_markdown-toolbar-element_dist_index_js-ceef33f593fa.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_file-attachment-element_dist_index_js-node_modules_primer_view-co-c44a69-8094ee2ecc5e.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/github-elements-c5fd390b3ba0.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/element-registry-b91e8c7aa0b9.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_braintree_browser-detection_dist_browser-detection_js-node_modules_githu-bb80ec-72267f4e3ff9.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_lit-html_lit-html_js-be8cb88f481b.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_mini-throttle_dist_index_js-node_modules_morphdom_dist_morphdom-e-7c534c-a4a1922eb55f.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_turbo_dist_turbo_es2017-esm_js-e3cbe28f1638.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_remote-form_dist_index_js-node_modules_delegated-events_dist_inde-893f9f-6cf3320416b8.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_color-convert_index_js-e3180fe3bcb3.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_quote-selection_dist_index_js-node_modules_github_session-resume_-69cfcc-bc42a18e77d5.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_updatable-content_updatable-content_ts-a1563f62660e.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/app_assets_modules_github_behaviors_task-list_ts-app_assets_modules_github_sso_ts-ui_packages-900dde-035d0557f18e.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/app_assets_modules_github_sticky-scroll-into-view_ts-3e000c5d31a9.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/app_assets_modules_github_behaviors_ajax-error_ts-app_assets_modules_github_behaviors_include-87a4ae-97019968d380.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/app_assets_modules_github_behaviors_commenting_edit_ts-app_assets_modules_github_behaviors_ht-83c235-e429cff6ceb1.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/behaviors-8ac983183615.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_delegated-events_dist_index_js-node_modules_github_catalyst_lib_index_js-f6223d90c7ba.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/notifications-global-01e85cd1be94.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_mini-throttle_dist_index_js-node_modules_github_catalyst_lib_inde-dbbea9-26cce2010167.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/code-menu-1c0aedc134b1.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/primer-react-9a5713772ca5.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/react-core-d0cc61cb9985.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/react-lib-f1bca44e0926.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/octicons-react-611691cca2f6.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_emotion_is-prop-valid_dist_emotion-is-prop-valid_esm_js-node_modules_emo-62da9f-2df2f32ec596.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_mini-throttle_dist_index_js-node_modules_stacktrace-parser_dist_s-e7dcdd-f7cc96ebae76.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_oddbird_popover-polyfill_dist_popover-fn_js-55fea94174bf.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_dompurify_dist_purify_js-b89b98661809.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_lodash-es__Stack_js-node_modules_lodash-es__Uint8Array_js-node_modules_l-4faaa6-4a736fde5c2f.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_lodash-es__baseIsEqual_js-8929eb9718d5.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_hydro-analytics-client_dist_analytics-client_js-node_modules_gith-40531a-09af0ef9a562.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_aria-live_aria-live_ts-ui_packages_promise-with-resolvers-polyfill_promise-with-r-17c672-d6b5ea82572a.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_paths_index_ts-8b8414d250a8.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_ref-selector_RefSelector_tsx-7496afc3784d.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_diffs_diff-parts_ts-555a13945c12.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_code-view-shared_worker-jobs_debounced-worker-manager_ts-ui_packages_commit-attri-a6ddb4-3e35b26a503b.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_code-view-shared_hooks_use-canonical-object_ts-ui_packages_code-view-shared_hooks-a6859a-51fe787d3cdc.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_repos-file-tree-view_repos-file-tree-view_ts-ui_packages_feature-request_FeatureR-648c3b-ad58d952149e.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/app_assets_modules_github_blob-anchor_ts-ui_packages_code-nav_code-nav_ts-ui_packages_filter--8253c1-91468a3354f9.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/react-code-view-56d3e189774d.js"></script> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react.2b41f48ec06f29182cb4.module.css" /> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/react-code-view.ab7d8fac328c00e5e0cc.module.css" /> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/notifications-subscriptions-menu-4a07d5e6bdd6.js"></script> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react.2b41f48ec06f29182cb4.module.css" /> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/notifications-subscriptions-menu.1bcff9205c241e99cff2.module.css" /> <title>amphtml/extensions/amp-a4a/rtc-documentation.md at main · ampproject/amphtml · GitHub</title> <meta name="route-pattern" content="/:user_id/:repository/blob/*name(/*path)" data-turbo-transient> <meta name="route-controller" content="blob" data-turbo-transient> <meta name="route-action" content="show" data-turbo-transient> <meta name="current-catalog-service-hash" content="f3abb0cc802f3d7b95fc8762b94bdcb13bf39634c40c357301c4aa1d67a256fb"> <meta name="request-id" content="90C0:12ED2E:244EBF:2C439C:67BF6E31" data-pjax-transient="true"/><meta name="html-safe-nonce" content="d3b6c26089b8dba58dd02d1425154133ce5b2329a59d440985e5aab5df67b5c4" data-pjax-transient="true"/><meta name="visitor-payload" content="eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI5MEMwOjEyRUQyRToyNDRFQkY6MkM0MzlDOjY3QkY2RTMxIiwidmlzaXRvcl9pZCI6IjYzODU0NzAzNzQ4MzM3NzgyMjUiLCJyZWdpb25fZWRnZSI6InNvdXRoZWFzdGFzaWEiLCJyZWdpb25fcmVuZGVyIjoic291dGhlYXN0YXNpYSJ9" data-pjax-transient="true"/><meta name="visitor-hmac" content="f0199a2fa598740e4e9a17c026b9af01ff496e0223e8b1cc1e4ad531450a5549" data-pjax-transient="true"/> <meta name="hovercard-subject-tag" content="repository:41766002" data-turbo-transient> <meta name="github-keyboard-shortcuts" content="repository,source-code,file-tree,copilot" data-turbo-transient="true" /> <meta name="selected-link" value="repo_source" data-turbo-transient> <link rel="assets" href="https://github.githubassets.com/"> <meta name="google-site-verification" content="Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I"> <meta name="octolytics-url" content="https://collector.github.com/github/collect" /> <meta name="analytics-location" content="/&lt;user-name&gt;/&lt;repo-name&gt;/blob/show" data-turbo-transient="true" /> <meta name="user-login" content=""> <meta name="viewport" content="width=device-width"> <meta name="description" content="The AMP web component framework. Contribute to ampproject/amphtml development by creating an account on GitHub."> <link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub"> <link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub"> <meta property="fb:app_id" content="1401488693436528"> <meta name="apple-itunes-app" content="app-id=1477376905, app-argument=https://github.com/ampproject/amphtml/blob/main/extensions/amp-a4a/rtc-documentation.md" /> <meta name="twitter:image" content="https://repository-images.githubusercontent.com/41766002/4d822280-678b-11e9-8fad-f0479a11cbcc" /><meta name="twitter:site" content="@github" /><meta name="twitter:card" content="summary_large_image" /><meta name="twitter:title" content="amphtml/extensions/amp-a4a/rtc-documentation.md at main · ampproject/amphtml" /><meta name="twitter:description" content="The AMP web component framework. Contribute to ampproject/amphtml development by creating an account on GitHub." /> <meta property="og:image" content="https://repository-images.githubusercontent.com/41766002/4d822280-678b-11e9-8fad-f0479a11cbcc" /><meta property="og:image:alt" content="The AMP web component framework. Contribute to ampproject/amphtml development by creating an account on GitHub." /><meta property="og:site_name" content="GitHub" /><meta property="og:type" content="object" /><meta property="og:title" content="amphtml/extensions/amp-a4a/rtc-documentation.md at main · ampproject/amphtml" /><meta property="og:url" content="https://github.com/ampproject/amphtml/blob/main/extensions/amp-a4a/rtc-documentation.md" /><meta property="og:description" content="The AMP web component framework. Contribute to ampproject/amphtml development by creating an account on GitHub." /> <meta name="hostname" content="github.com"> <meta name="expected-hostname" content="github.com"> <meta http-equiv="x-pjax-version" content="19ce5e9d3b8db63d64afa203a5ff1a7f08c32c6883f1da90f5af44a196541cb5" data-turbo-track="reload"> <meta http-equiv="x-pjax-csp-version" content="ace39c3b6632770952207593607e6e0be0db363435a8b877b1f96abe6430f345" data-turbo-track="reload"> <meta http-equiv="x-pjax-css-version" content="249d206a8cd18f10036cb45c470746438fc2c46dae40dbaa0f80bb8c4539b047" data-turbo-track="reload"> <meta http-equiv="x-pjax-js-version" content="dd3593079b5f5c9a95640f89c04b7c1839c6841825057a8186e4c1d4017fed03" data-turbo-track="reload"> <meta name="turbo-cache-control" content="no-preview" data-turbo-transient=""> <meta name="turbo-cache-control" content="no-cache" data-turbo-transient> <meta data-hydrostats="publish"> <meta name="go-import" content="github.com/ampproject/amphtml git https://github.com/ampproject/amphtml.git"> <meta name="octolytics-dimension-user_id" content="14114390" /><meta name="octolytics-dimension-user_login" content="ampproject" /><meta name="octolytics-dimension-repository_id" content="41766002" /><meta name="octolytics-dimension-repository_nwo" content="ampproject/amphtml" /><meta name="octolytics-dimension-repository_public" content="true" /><meta name="octolytics-dimension-repository_is_fork" content="false" /><meta name="octolytics-dimension-repository_network_root_id" content="41766002" /><meta name="octolytics-dimension-repository_network_root_nwo" content="ampproject/amphtml" /> <meta name="turbo-body-classes" content="logged-out env-production page-responsive"> <meta name="browser-stats-url" content="https://api.github.com/_private/browser/stats"> <meta name="browser-errors-url" content="https://api.github.com/_private/browser/errors"> <link rel="mask-icon" href="https://github.githubassets.com/assets/pinned-octocat-093da3e6fa40.svg" color="#000000"> <link rel="alternate icon" class="js-site-favicon" type="image/png" href="https://github.githubassets.com/favicons/favicon.png"> <link rel="icon" class="js-site-favicon" type="image/svg+xml" href="https://github.githubassets.com/favicons/favicon.svg" data-base-href="https://github.githubassets.com/favicons/favicon"> <meta name="theme-color" content="#1e2327"> <meta name="color-scheme" content="light dark" /> <link rel="manifest" href="/manifest.json" crossOrigin="use-credentials"> </head> <body class="logged-out env-production page-responsive" style="word-wrap: break-word;"> <div data-turbo-body class="logged-out env-production page-responsive" style="word-wrap: break-word;"> <div class="position-relative header-wrapper js-header-wrapper "> <a href="#start-of-content" data-skip-target-assigned="false" class="px-2 py-4 color-bg-accent-emphasis color-fg-on-emphasis show-on-focus js-skip-to-content">Skip to content</a> <span data-view-component="true" class="progress-pjax-loader Progress position-fixed width-full"> <span style="width: 0%;" data-view-component="true" class="Progress-item progress-pjax-loader-bar left-0 top-0 color-bg-accent-emphasis"></span> </span> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_ui-commands_ui-commands_ts-97496b0f52ba.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/keyboard-shortcuts-dialog-c79a97a16b04.js"></script> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react.2b41f48ec06f29182cb4.module.css" /> <react-partial partial-name="keyboard-shortcuts-dialog" data-ssr="false" data-attempted-ssr="false" > <script type="application/json" data-target="react-partial.embeddedData">{"props":{"docsUrl":"https://docs.github.com/get-started/accessibility/keyboard-shortcuts"}}</script> <div data-target="react-partial.reactRoot"></div> </react-partial> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_remote-form_dist_index_js-node_modules_delegated-events_dist_inde-94fd67-56e2d9924e94.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/sessions-730dca81d0a2.js"></script> <header class="HeaderMktg header-logged-out js-details-container js-header Details f4 py-3" role="banner" data-is-top="true" data-color-mode=light data-light-theme=light data-dark-theme=dark> <h2 class="sr-only">Navigation Menu</h2> <button type="button" class="HeaderMktg-backdrop d-lg-none border-0 position-fixed top-0 left-0 width-full height-full js-details-target" aria-label="Toggle navigation"> <span class="d-none">Toggle navigation</span> </button> <div class="d-flex flex-column flex-lg-row flex-items-center px-3 px-md-4 px-lg-5 height-full position-relative z-1"> <div class="d-flex flex-justify-between flex-items-center width-full width-lg-auto"> <div class="flex-1"> <button aria-label="Toggle navigation" aria-expanded="false" type="button" data-view-component="true" class="js-details-target js-nav-padding-recalculate js-header-menu-toggle Button--link Button--medium Button d-lg-none color-fg-inherit p-1"> <span class="Button-content"> <span class="Button-label"><div class="HeaderMenu-toggle-bar rounded my-1"></div> <div class="HeaderMenu-toggle-bar rounded my-1"></div> <div class="HeaderMenu-toggle-bar rounded my-1"></div></span> </span> </button> </div> <a class="mr-lg-3 color-fg-inherit flex-order-2 js-prevent-focus-on-mobile-nav" href="/" aria-label="Homepage" data-analytics-event="{&quot;category&quot;:&quot;Marketing nav&quot;,&quot;action&quot;:&quot;click to go to homepage&quot;,&quot;label&quot;:&quot;ref_page:Marketing;ref_cta:Logomark;ref_loc:Header&quot;}"> <svg height="32" aria-hidden="true" viewBox="0 0 24 24" version="1.1" width="32" data-view-component="true" class="octicon octicon-mark-github"> <path d="M12.5.75C6.146.75 1 5.896 1 12.25c0 5.089 3.292 9.387 7.863 10.91.575.101.79-.244.79-.546 0-.273-.014-1.178-.014-2.142-2.889.532-3.636-.704-3.866-1.35-.13-.331-.69-1.352-1.18-1.625-.402-.216-.977-.748-.014-.762.906-.014 1.553.834 1.769 1.179 1.035 1.74 2.688 1.25 3.349.948.1-.747.402-1.25.733-1.538-2.559-.287-5.232-1.279-5.232-5.678 0-1.25.445-2.285 1.178-3.09-.115-.288-.517-1.467.115-3.048 0 0 .963-.302 3.163 1.179.92-.259 1.897-.388 2.875-.388.977 0 1.955.13 2.875.388 2.2-1.495 3.162-1.179 3.162-1.179.633 1.581.23 2.76.115 3.048.733.805 1.179 1.825 1.179 3.09 0 4.413-2.688 5.39-5.247 5.678.417.36.776 1.05.776 2.128 0 1.538-.014 2.774-.014 3.162 0 .302.216.662.79.547C20.709 21.637 24 17.324 24 12.25 24 5.896 18.854.75 12.5.75Z"></path> </svg> </a> <div class="flex-1 flex-order-2 text-right"> <a href="/login?return_to=https%3A%2F%2Fgithub.com%2Fampproject%2Famphtml%2Fblob%2Fmain%2Fextensions%2Famp-a4a%2Frtc-documentation.md" class="HeaderMenu-link HeaderMenu-button d-inline-flex d-lg-none flex-order-1 f5 no-underline border color-border-default rounded-2 px-2 py-1 color-fg-inherit js-prevent-focus-on-mobile-nav" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header menu&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/ampproject/amphtml/blob/main/extensions/amp-a4a/rtc-documentation.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="32cb0e328f9c6ea29ab66592e3cf515810bd8783fd8fecea3ff1753a8d1aba1c" data-analytics-event="{&quot;category&quot;:&quot;Marketing nav&quot;,&quot;action&quot;:&quot;click to Sign in&quot;,&quot;label&quot;:&quot;ref_page:Marketing;ref_cta:Sign in;ref_loc:Header&quot;}" > Sign in </a> </div> </div> <div class="HeaderMenu js-header-menu height-fit position-lg-relative d-lg-flex flex-column flex-auto top-0"> <div class="HeaderMenu-wrapper d-flex flex-column flex-self-start flex-lg-row flex-auto rounded rounded-lg-0"> <nav class="HeaderMenu-nav" aria-label="Global"> <ul class="d-lg-flex list-style-none"> <li class="HeaderMenu-item position-relative flex-wrap flex-justify-between flex-items-center d-block d-lg-flex flex-lg-nowrap flex-lg-items-center js-details-container js-header-menu-item"> <button type="button" class="HeaderMenu-link border-0 width-full width-lg-auto px-0 px-lg-2 py-lg-2 no-wrap d-flex flex-items-center flex-justify-between js-details-target" aria-expanded="false"> Product <svg opacity="0.5" aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-chevron-down HeaderMenu-icon ml-1"> <path d="M12.78 5.22a.749.749 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.06 0L3.22 6.28a.749.749 0 1 1 1.06-1.06L8 8.939l3.72-3.719a.749.749 0 0 1 1.06 0Z"></path> </svg> </button> <div class="HeaderMenu-dropdown dropdown-menu rounded m-0 p-0 pt-2 pt-lg-4 position-relative position-lg-absolute left-0 left-lg-n3 pb-2 pb-lg-4 d-lg-flex flex-wrap dropdown-menu-wide"> <div class="HeaderMenu-column px-lg-4 border-lg-right mb-4 mb-lg-0 pr-lg-7"> <div class="border-bottom pb-3 pb-lg-0 border-lg-bottom-0"> <ul class="list-style-none f5" > <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description pb-lg-3" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;github_copilot&quot;,&quot;context&quot;:&quot;product&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;github_copilot_link_product_navbar&quot;}" href="https://github.com/features/copilot"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-copilot color-fg-subtle mr-3"> <path d="M23.922 16.992c-.861 1.495-5.859 5.023-11.922 5.023-6.063 0-11.061-3.528-11.922-5.023A.641.641 0 0 1 0 16.736v-2.869a.841.841 0 0 1 .053-.22c.372-.935 1.347-2.292 2.605-2.656.167-.429.414-1.055.644-1.517a10.195 10.195 0 0 1-.052-1.086c0-1.331.282-2.499 1.132-3.368.397-.406.89-.717 1.474-.952 1.399-1.136 3.392-2.093 6.122-2.093 2.731 0 4.767.957 6.166 2.093.584.235 1.077.546 1.474.952.85.869 1.132 2.037 1.132 3.368 0 .368-.014.733-.052 1.086.23.462.477 1.088.644 1.517 1.258.364 2.233 1.721 2.605 2.656a.832.832 0 0 1 .053.22v2.869a.641.641 0 0 1-.078.256ZM12.172 11h-.344a4.323 4.323 0 0 1-.355.508C10.703 12.455 9.555 13 7.965 13c-1.725 0-2.989-.359-3.782-1.259a2.005 2.005 0 0 1-.085-.104L4 11.741v6.585c1.435.779 4.514 2.179 8 2.179 3.486 0 6.565-1.4 8-2.179v-6.585l-.098-.104s-.033.045-.085.104c-.793.9-2.057 1.259-3.782 1.259-1.59 0-2.738-.545-3.508-1.492a4.323 4.323 0 0 1-.355-.508h-.016.016Zm.641-2.935c.136 1.057.403 1.913.878 2.497.442.544 1.134.938 2.344.938 1.573 0 2.292-.337 2.657-.751.384-.435.558-1.15.558-2.361 0-1.14-.243-1.847-.705-2.319-.477-.488-1.319-.862-2.824-1.025-1.487-.161-2.192.138-2.533.529-.269.307-.437.808-.438 1.578v.021c0 .265.021.562.063.893Zm-1.626 0c.042-.331.063-.628.063-.894v-.02c-.001-.77-.169-1.271-.438-1.578-.341-.391-1.046-.69-2.533-.529-1.505.163-2.347.537-2.824 1.025-.462.472-.705 1.179-.705 2.319 0 1.211.175 1.926.558 2.361.365.414 1.084.751 2.657.751 1.21 0 1.902-.394 2.344-.938.475-.584.742-1.44.878-2.497Z"></path><path d="M14.5 14.25a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0v-2a1 1 0 0 1 1-1Zm-5 0a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0v-2a1 1 0 0 1 1-1Z"></path> </svg> <div> <div class="color-fg-default h4">GitHub Copilot</div> Write better code with AI </div> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description pb-lg-3" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;security&quot;,&quot;context&quot;:&quot;product&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;security_link_product_navbar&quot;}" href="https://github.com/features/security"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-shield-check color-fg-subtle mr-3"> <path d="M16.53 9.78a.75.75 0 0 0-1.06-1.06L11 13.19l-1.97-1.97a.75.75 0 0 0-1.06 1.06l2.5 2.5a.75.75 0 0 0 1.06 0l5-5Z"></path><path d="m12.54.637 8.25 2.675A1.75 1.75 0 0 1 22 4.976V10c0 6.19-3.771 10.704-9.401 12.83a1.704 1.704 0 0 1-1.198 0C5.77 20.705 2 16.19 2 10V4.976c0-.758.489-1.43 1.21-1.664L11.46.637a1.748 1.748 0 0 1 1.08 0Zm-.617 1.426-8.25 2.676a.249.249 0 0 0-.173.237V10c0 5.46 3.28 9.483 8.43 11.426a.199.199 0 0 0 .14 0C17.22 19.483 20.5 15.461 20.5 10V4.976a.25.25 0 0 0-.173-.237l-8.25-2.676a.253.253 0 0 0-.154 0Z"></path> </svg> <div> <div class="color-fg-default h4">Security</div> Find and fix vulnerabilities </div> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description pb-lg-3" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;actions&quot;,&quot;context&quot;:&quot;product&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;actions_link_product_navbar&quot;}" href="https://github.com/features/actions"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-workflow color-fg-subtle mr-3"> <path d="M1 3a2 2 0 0 1 2-2h6.5a2 2 0 0 1 2 2v6.5a2 2 0 0 1-2 2H7v4.063C7 16.355 7.644 17 8.438 17H12.5v-2.5a2 2 0 0 1 2-2H21a2 2 0 0 1 2 2V21a2 2 0 0 1-2 2h-6.5a2 2 0 0 1-2-2v-2.5H8.437A2.939 2.939 0 0 1 5.5 15.562V11.5H3a2 2 0 0 1-2-2Zm2-.5a.5.5 0 0 0-.5.5v6.5a.5.5 0 0 0 .5.5h6.5a.5.5 0 0 0 .5-.5V3a.5.5 0 0 0-.5-.5ZM14.5 14a.5.5 0 0 0-.5.5V21a.5.5 0 0 0 .5.5H21a.5.5 0 0 0 .5-.5v-6.5a.5.5 0 0 0-.5-.5Z"></path> </svg> <div> <div class="color-fg-default h4">Actions</div> Automate any workflow </div> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description pb-lg-3" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;codespaces&quot;,&quot;context&quot;:&quot;product&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;codespaces_link_product_navbar&quot;}" href="https://github.com/features/codespaces"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-codespaces color-fg-subtle mr-3"> <path d="M3.5 3.75C3.5 2.784 4.284 2 5.25 2h13.5c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0 1 18.75 13H5.25a1.75 1.75 0 0 1-1.75-1.75Zm-2 12c0-.966.784-1.75 1.75-1.75h17.5c.966 0 1.75.784 1.75 1.75v4a1.75 1.75 0 0 1-1.75 1.75H3.25a1.75 1.75 0 0 1-1.75-1.75ZM5.25 3.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h13.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Zm-2 12a.25.25 0 0 0-.25.25v4c0 .138.112.25.25.25h17.5a.25.25 0 0 0 .25-.25v-4a.25.25 0 0 0-.25-.25Z"></path><path d="M10 17.75a.75.75 0 0 1 .75-.75h6.5a.75.75 0 0 1 0 1.5h-6.5a.75.75 0 0 1-.75-.75Zm-4 0a.75.75 0 0 1 .75-.75h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1-.75-.75Z"></path> </svg> <div> <div class="color-fg-default h4">Codespaces</div> Instant dev environments </div> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description pb-lg-3" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;issues&quot;,&quot;context&quot;:&quot;product&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;issues_link_product_navbar&quot;}" href="https://github.com/features/issues"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-issue-opened color-fg-subtle mr-3"> <path d="M12 1c6.075 0 11 4.925 11 11s-4.925 11-11 11S1 18.075 1 12 5.925 1 12 1ZM2.5 12a9.5 9.5 0 0 0 9.5 9.5 9.5 9.5 0 0 0 9.5-9.5A9.5 9.5 0 0 0 12 2.5 9.5 9.5 0 0 0 2.5 12Zm9.5 2a2 2 0 1 1-.001-3.999A2 2 0 0 1 12 14Z"></path> </svg> <div> <div class="color-fg-default h4">Issues</div> Plan and track work </div> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description pb-lg-3" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;code_review&quot;,&quot;context&quot;:&quot;product&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;code_review_link_product_navbar&quot;}" href="https://github.com/features/code-review"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-code-review color-fg-subtle mr-3"> <path d="M10.3 6.74a.75.75 0 0 1-.04 1.06l-2.908 2.7 2.908 2.7a.75.75 0 1 1-1.02 1.1l-3.5-3.25a.75.75 0 0 1 0-1.1l3.5-3.25a.75.75 0 0 1 1.06.04Zm3.44 1.06a.75.75 0 1 1 1.02-1.1l3.5 3.25a.75.75 0 0 1 0 1.1l-3.5 3.25a.75.75 0 1 1-1.02-1.1l2.908-2.7-2.908-2.7Z"></path><path d="M1.5 4.25c0-.966.784-1.75 1.75-1.75h17.5c.966 0 1.75.784 1.75 1.75v12.5a1.75 1.75 0 0 1-1.75 1.75h-9.69l-3.573 3.573A1.458 1.458 0 0 1 5 21.043V18.5H3.25a1.75 1.75 0 0 1-1.75-1.75ZM3.25 4a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h2.5a.75.75 0 0 1 .75.75v3.19l3.72-3.72a.749.749 0 0 1 .53-.22h10a.25.25 0 0 0 .25-.25V4.25a.25.25 0 0 0-.25-.25Z"></path> </svg> <div> <div class="color-fg-default h4">Code Review</div> Manage code changes </div> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description pb-lg-3" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;discussions&quot;,&quot;context&quot;:&quot;product&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;discussions_link_product_navbar&quot;}" href="https://github.com/features/discussions"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-comment-discussion color-fg-subtle mr-3"> <path d="M1.75 1h12.5c.966 0 1.75.784 1.75 1.75v9.5A1.75 1.75 0 0 1 14.25 14H8.061l-2.574 2.573A1.458 1.458 0 0 1 3 15.543V14H1.75A1.75 1.75 0 0 1 0 12.25v-9.5C0 1.784.784 1 1.75 1ZM1.5 2.75v9.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-9.5a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25Z"></path><path d="M22.5 8.75a.25.25 0 0 0-.25-.25h-3.5a.75.75 0 0 1 0-1.5h3.5c.966 0 1.75.784 1.75 1.75v9.5A1.75 1.75 0 0 1 22.25 20H21v1.543a1.457 1.457 0 0 1-2.487 1.03L15.939 20H10.75A1.75 1.75 0 0 1 9 18.25v-1.465a.75.75 0 0 1 1.5 0v1.465c0 .138.112.25.25.25h5.5a.75.75 0 0 1 .53.22l2.72 2.72v-2.19a.75.75 0 0 1 .75-.75h2a.25.25 0 0 0 .25-.25v-9.5Z"></path> </svg> <div> <div class="color-fg-default h4">Discussions</div> Collaborate outside of code </div> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;code_search&quot;,&quot;context&quot;:&quot;product&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;code_search_link_product_navbar&quot;}" href="https://github.com/features/code-search"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-code-square color-fg-subtle mr-3"> <path d="M10.3 8.24a.75.75 0 0 1-.04 1.06L7.352 12l2.908 2.7a.75.75 0 1 1-1.02 1.1l-3.5-3.25a.75.75 0 0 1 0-1.1l3.5-3.25a.75.75 0 0 1 1.06.04Zm3.44 1.06a.75.75 0 1 1 1.02-1.1l3.5 3.25a.75.75 0 0 1 0 1.1l-3.5 3.25a.75.75 0 1 1-1.02-1.1l2.908-2.7-2.908-2.7Z"></path><path d="M2 3.75C2 2.784 2.784 2 3.75 2h16.5c.966 0 1.75.784 1.75 1.75v16.5A1.75 1.75 0 0 1 20.25 22H3.75A1.75 1.75 0 0 1 2 20.25Zm1.75-.25a.25.25 0 0 0-.25.25v16.5c0 .138.112.25.25.25h16.5a.25.25 0 0 0 .25-.25V3.75a.25.25 0 0 0-.25-.25Z"></path> </svg> <div> <div class="color-fg-default h4">Code Search</div> Find more, search less </div> </a></li> </ul> </div> </div> <div class="HeaderMenu-column px-lg-4"> <div class="border-bottom pb-3 pb-lg-0 border-lg-bottom-0 border-bottom-0"> <span class="d-block h4 color-fg-default my-1" id="product-explore-heading">Explore</span> <ul class="list-style-none f5" aria-labelledby="product-explore-heading"> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;all_features&quot;,&quot;context&quot;:&quot;product&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;all_features_link_product_navbar&quot;}" href="https://github.com/features"> All features </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary Link--external" target="_blank" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;documentation&quot;,&quot;context&quot;:&quot;product&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;documentation_link_product_navbar&quot;}" href="https://docs.github.com"> Documentation <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-link-external HeaderMenu-external-icon color-fg-subtle"> <path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path> </svg> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary Link--external" target="_blank" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;github_skills&quot;,&quot;context&quot;:&quot;product&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;github_skills_link_product_navbar&quot;}" href="https://skills.github.com"> GitHub Skills <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-link-external HeaderMenu-external-icon color-fg-subtle"> <path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path> </svg> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary Link--external" target="_blank" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;blog&quot;,&quot;context&quot;:&quot;product&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;blog_link_product_navbar&quot;}" href="https://github.blog"> Blog <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-link-external HeaderMenu-external-icon color-fg-subtle"> <path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path> </svg> </a></li> </ul> </div> </div> </div> </li> <li class="HeaderMenu-item position-relative flex-wrap flex-justify-between flex-items-center d-block d-lg-flex flex-lg-nowrap flex-lg-items-center js-details-container js-header-menu-item"> <button type="button" class="HeaderMenu-link border-0 width-full width-lg-auto px-0 px-lg-2 py-lg-2 no-wrap d-flex flex-items-center flex-justify-between js-details-target" aria-expanded="false"> Solutions <svg opacity="0.5" aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-chevron-down HeaderMenu-icon ml-1"> <path d="M12.78 5.22a.749.749 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.06 0L3.22 6.28a.749.749 0 1 1 1.06-1.06L8 8.939l3.72-3.719a.749.749 0 0 1 1.06 0Z"></path> </svg> </button> <div class="HeaderMenu-dropdown dropdown-menu rounded m-0 p-0 pt-2 pt-lg-4 position-relative position-lg-absolute left-0 left-lg-n3 d-lg-flex flex-wrap dropdown-menu-wide"> <div class="HeaderMenu-column px-lg-4 border-lg-right mb-4 mb-lg-0 pr-lg-7"> <div class="border-bottom pb-3 pb-lg-0 border-lg-bottom-0 pb-lg-3 mb-3 mb-lg-0"> <span class="d-block h4 color-fg-default my-1" id="solutions-by-company-size-heading">By company size</span> <ul class="list-style-none f5" aria-labelledby="solutions-by-company-size-heading"> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;enterprises&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;enterprises_link_solutions_navbar&quot;}" href="https://github.com/enterprise"> Enterprises </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;small_and_medium_teams&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;small_and_medium_teams_link_solutions_navbar&quot;}" href="https://github.com/team"> Small and medium teams </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;startups&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;startups_link_solutions_navbar&quot;}" href="https://github.com/enterprise/startups"> Startups </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;nonprofits&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;nonprofits_link_solutions_navbar&quot;}" href="/solutions/industry/nonprofits"> Nonprofits </a></li> </ul> </div> <div class="border-bottom pb-3 pb-lg-0 border-lg-bottom-0"> <span class="d-block h4 color-fg-default my-1" id="solutions-by-use-case-heading">By use case</span> <ul class="list-style-none f5" aria-labelledby="solutions-by-use-case-heading"> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;devsecops&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;devsecops_link_solutions_navbar&quot;}" href="/solutions/use-case/devsecops"> DevSecOps </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;devops&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;devops_link_solutions_navbar&quot;}" href="/solutions/use-case/devops"> DevOps </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;ci_cd&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;ci_cd_link_solutions_navbar&quot;}" href="/solutions/use-case/ci-cd"> CI/CD </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;view_all_use_cases&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;view_all_use_cases_link_solutions_navbar&quot;}" href="/solutions/use-case"> View all use cases </a></li> </ul> </div> </div> <div class="HeaderMenu-column px-lg-4"> <div class="border-bottom pb-3 pb-lg-0 border-lg-bottom-0"> <span class="d-block h4 color-fg-default my-1" id="solutions-by-industry-heading">By industry</span> <ul class="list-style-none f5" aria-labelledby="solutions-by-industry-heading"> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;healthcare&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;healthcare_link_solutions_navbar&quot;}" href="/solutions/industry/healthcare"> Healthcare </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;financial_services&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;financial_services_link_solutions_navbar&quot;}" href="/solutions/industry/financial-services"> Financial services </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;manufacturing&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;manufacturing_link_solutions_navbar&quot;}" href="/solutions/industry/manufacturing"> Manufacturing </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;government&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;government_link_solutions_navbar&quot;}" href="/solutions/industry/government"> Government </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;view_all_industries&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;view_all_industries_link_solutions_navbar&quot;}" href="/solutions/industry"> View all industries </a></li> </ul> </div> </div> <div class="HeaderMenu-trailing-link rounded-bottom-2 flex-shrink-0 mt-lg-4 px-lg-4 py-4 py-lg-3 f5 text-semibold"> <a href="/solutions"> View all solutions <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-chevron-right HeaderMenu-trailing-link-icon"> <path d="M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06Z"></path> </svg> </a> </div> </div> </li> <li class="HeaderMenu-item position-relative flex-wrap flex-justify-between flex-items-center d-block d-lg-flex flex-lg-nowrap flex-lg-items-center js-details-container js-header-menu-item"> <button type="button" class="HeaderMenu-link border-0 width-full width-lg-auto px-0 px-lg-2 py-lg-2 no-wrap d-flex flex-items-center flex-justify-between js-details-target" aria-expanded="false"> Resources <svg opacity="0.5" aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-chevron-down HeaderMenu-icon ml-1"> <path d="M12.78 5.22a.749.749 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.06 0L3.22 6.28a.749.749 0 1 1 1.06-1.06L8 8.939l3.72-3.719a.749.749 0 0 1 1.06 0Z"></path> </svg> </button> <div class="HeaderMenu-dropdown dropdown-menu rounded m-0 p-0 pt-2 pt-lg-4 position-relative position-lg-absolute left-0 left-lg-n3 pb-2 pb-lg-4 d-lg-flex flex-wrap dropdown-menu-wide"> <div class="HeaderMenu-column px-lg-4 border-lg-right mb-4 mb-lg-0 pr-lg-7"> <div class="border-bottom pb-3 pb-lg-0 border-lg-bottom-0"> <span class="d-block h4 color-fg-default my-1" id="resources-topics-heading">Topics</span> <ul class="list-style-none f5" aria-labelledby="resources-topics-heading"> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;ai&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;ai_link_resources_navbar&quot;}" href="/resources/articles/ai"> AI </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;devops&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;devops_link_resources_navbar&quot;}" href="/resources/articles/devops"> DevOps </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;security&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;security_link_resources_navbar&quot;}" href="/resources/articles/security"> Security </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;software_development&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;software_development_link_resources_navbar&quot;}" href="/resources/articles/software-development"> Software Development </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;view_all&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;view_all_link_resources_navbar&quot;}" href="/resources/articles"> View all </a></li> </ul> </div> </div> <div class="HeaderMenu-column px-lg-4"> <div class="border-bottom pb-3 pb-lg-0 border-lg-bottom-0 border-bottom-0"> <span class="d-block h4 color-fg-default my-1" id="resources-explore-heading">Explore</span> <ul class="list-style-none f5" aria-labelledby="resources-explore-heading"> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary Link--external" target="_blank" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;learning_pathways&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;learning_pathways_link_resources_navbar&quot;}" href="https://resources.github.com/learn/pathways"> Learning Pathways <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-link-external HeaderMenu-external-icon color-fg-subtle"> <path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path> </svg> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary Link--external" target="_blank" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;events_amp_webinars&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;events_amp_webinars_link_resources_navbar&quot;}" href="https://resources.github.com"> Events &amp; Webinars <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-link-external HeaderMenu-external-icon color-fg-subtle"> <path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path> </svg> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;ebooks_amp_whitepapers&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;ebooks_amp_whitepapers_link_resources_navbar&quot;}" href="https://github.com/resources/whitepapers"> Ebooks &amp; Whitepapers </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;customer_stories&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;customer_stories_link_resources_navbar&quot;}" href="https://github.com/customer-stories"> Customer Stories </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary Link--external" target="_blank" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;partners&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;partners_link_resources_navbar&quot;}" href="https://partner.github.com"> Partners <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-link-external HeaderMenu-external-icon color-fg-subtle"> <path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path> </svg> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;executive_insights&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;executive_insights_link_resources_navbar&quot;}" href="https://github.com/solutions/executive-insights"> Executive Insights </a></li> </ul> </div> </div> </div> </li> <li class="HeaderMenu-item position-relative flex-wrap flex-justify-between flex-items-center d-block d-lg-flex flex-lg-nowrap flex-lg-items-center js-details-container js-header-menu-item"> <button type="button" class="HeaderMenu-link border-0 width-full width-lg-auto px-0 px-lg-2 py-lg-2 no-wrap d-flex flex-items-center flex-justify-between js-details-target" aria-expanded="false"> Open Source <svg opacity="0.5" aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-chevron-down HeaderMenu-icon ml-1"> <path d="M12.78 5.22a.749.749 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.06 0L3.22 6.28a.749.749 0 1 1 1.06-1.06L8 8.939l3.72-3.719a.749.749 0 0 1 1.06 0Z"></path> </svg> </button> <div class="HeaderMenu-dropdown dropdown-menu rounded m-0 p-0 pt-2 pt-lg-4 position-relative position-lg-absolute left-0 left-lg-n3 pb-2 pb-lg-4 px-lg-4"> <div class="HeaderMenu-column"> <div class="border-bottom pb-3 pb-lg-0 pb-lg-3 mb-3 mb-lg-0 mb-lg-3"> <ul class="list-style-none f5" > <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;github_sponsors&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;github_sponsors_link_open_source_navbar&quot;}" href="/sponsors"> <div> <div class="color-fg-default h4">GitHub Sponsors</div> Fund open source developers </div> </a></li> </ul> </div> <div class="border-bottom pb-3 pb-lg-0 pb-lg-3 mb-3 mb-lg-0 mb-lg-3"> <ul class="list-style-none f5" > <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;the_readme_project&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;the_readme_project_link_open_source_navbar&quot;}" href="https://github.com/readme"> <div> <div class="color-fg-default h4">The ReadME Project</div> GitHub community articles </div> </a></li> </ul> </div> <div class="border-bottom pb-3 pb-lg-0 border-bottom-0"> <span class="d-block h4 color-fg-default my-1" id="open-source-repositories-heading">Repositories</span> <ul class="list-style-none f5" aria-labelledby="open-source-repositories-heading"> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;topics&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;topics_link_open_source_navbar&quot;}" href="https://github.com/topics"> Topics </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;trending&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;trending_link_open_source_navbar&quot;}" href="https://github.com/trending"> Trending </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;collections&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;collections_link_open_source_navbar&quot;}" href="https://github.com/collections"> Collections </a></li> </ul> </div> </div> </div> </li> <li class="HeaderMenu-item position-relative flex-wrap flex-justify-between flex-items-center d-block d-lg-flex flex-lg-nowrap flex-lg-items-center js-details-container js-header-menu-item"> <button type="button" class="HeaderMenu-link border-0 width-full width-lg-auto px-0 px-lg-2 py-lg-2 no-wrap d-flex flex-items-center flex-justify-between js-details-target" aria-expanded="false"> Enterprise <svg opacity="0.5" aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-chevron-down HeaderMenu-icon ml-1"> <path d="M12.78 5.22a.749.749 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.06 0L3.22 6.28a.749.749 0 1 1 1.06-1.06L8 8.939l3.72-3.719a.749.749 0 0 1 1.06 0Z"></path> </svg> </button> <div class="HeaderMenu-dropdown dropdown-menu rounded m-0 p-0 pt-2 pt-lg-4 position-relative position-lg-absolute left-0 left-lg-n3 pb-2 pb-lg-4 px-lg-4"> <div class="HeaderMenu-column"> <div class="border-bottom pb-3 pb-lg-0 pb-lg-3 mb-3 mb-lg-0 mb-lg-3"> <ul class="list-style-none f5" > <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;enterprise_platform&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;enterprise_platform_link_enterprise_navbar&quot;}" href="/enterprise"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-stack color-fg-subtle mr-3"> <path d="M11.063 1.456a1.749 1.749 0 0 1 1.874 0l8.383 5.316a1.751 1.751 0 0 1 0 2.956l-8.383 5.316a1.749 1.749 0 0 1-1.874 0L2.68 9.728a1.751 1.751 0 0 1 0-2.956Zm1.071 1.267a.25.25 0 0 0-.268 0L3.483 8.039a.25.25 0 0 0 0 .422l8.383 5.316a.25.25 0 0 0 .268 0l8.383-5.316a.25.25 0 0 0 0-.422Z"></path><path d="M1.867 12.324a.75.75 0 0 1 1.035-.232l8.964 5.685a.25.25 0 0 0 .268 0l8.964-5.685a.75.75 0 0 1 .804 1.267l-8.965 5.685a1.749 1.749 0 0 1-1.874 0l-8.965-5.685a.75.75 0 0 1-.231-1.035Z"></path><path d="M1.867 16.324a.75.75 0 0 1 1.035-.232l8.964 5.685a.25.25 0 0 0 .268 0l8.964-5.685a.75.75 0 0 1 .804 1.267l-8.965 5.685a1.749 1.749 0 0 1-1.874 0l-8.965-5.685a.75.75 0 0 1-.231-1.035Z"></path> </svg> <div> <div class="color-fg-default h4">Enterprise platform</div> AI-powered developer platform </div> </a></li> </ul> </div> <div class="border-bottom pb-3 pb-lg-0 border-bottom-0"> <span class="d-block h4 color-fg-default my-1" id="enterprise-available-add-ons-heading">Available add-ons</span> <ul class="list-style-none f5" aria-labelledby="enterprise-available-add-ons-heading"> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description pb-lg-3" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;advanced_security&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;advanced_security_link_enterprise_navbar&quot;}" href="https://github.com/enterprise/advanced-security"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-shield-check color-fg-subtle mr-3"> <path d="M16.53 9.78a.75.75 0 0 0-1.06-1.06L11 13.19l-1.97-1.97a.75.75 0 0 0-1.06 1.06l2.5 2.5a.75.75 0 0 0 1.06 0l5-5Z"></path><path d="m12.54.637 8.25 2.675A1.75 1.75 0 0 1 22 4.976V10c0 6.19-3.771 10.704-9.401 12.83a1.704 1.704 0 0 1-1.198 0C5.77 20.705 2 16.19 2 10V4.976c0-.758.489-1.43 1.21-1.664L11.46.637a1.748 1.748 0 0 1 1.08 0Zm-.617 1.426-8.25 2.676a.249.249 0 0 0-.173.237V10c0 5.46 3.28 9.483 8.43 11.426a.199.199 0 0 0 .14 0C17.22 19.483 20.5 15.461 20.5 10V4.976a.25.25 0 0 0-.173-.237l-8.25-2.676a.253.253 0 0 0-.154 0Z"></path> </svg> <div> <div class="color-fg-default h4">Advanced Security</div> Enterprise-grade security features </div> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description pb-lg-3" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;github_copilot&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;github_copilot_link_enterprise_navbar&quot;}" href="/features/copilot#enterprise"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-copilot color-fg-subtle mr-3"> <path d="M23.922 16.992c-.861 1.495-5.859 5.023-11.922 5.023-6.063 0-11.061-3.528-11.922-5.023A.641.641 0 0 1 0 16.736v-2.869a.841.841 0 0 1 .053-.22c.372-.935 1.347-2.292 2.605-2.656.167-.429.414-1.055.644-1.517a10.195 10.195 0 0 1-.052-1.086c0-1.331.282-2.499 1.132-3.368.397-.406.89-.717 1.474-.952 1.399-1.136 3.392-2.093 6.122-2.093 2.731 0 4.767.957 6.166 2.093.584.235 1.077.546 1.474.952.85.869 1.132 2.037 1.132 3.368 0 .368-.014.733-.052 1.086.23.462.477 1.088.644 1.517 1.258.364 2.233 1.721 2.605 2.656a.832.832 0 0 1 .053.22v2.869a.641.641 0 0 1-.078.256ZM12.172 11h-.344a4.323 4.323 0 0 1-.355.508C10.703 12.455 9.555 13 7.965 13c-1.725 0-2.989-.359-3.782-1.259a2.005 2.005 0 0 1-.085-.104L4 11.741v6.585c1.435.779 4.514 2.179 8 2.179 3.486 0 6.565-1.4 8-2.179v-6.585l-.098-.104s-.033.045-.085.104c-.793.9-2.057 1.259-3.782 1.259-1.59 0-2.738-.545-3.508-1.492a4.323 4.323 0 0 1-.355-.508h-.016.016Zm.641-2.935c.136 1.057.403 1.913.878 2.497.442.544 1.134.938 2.344.938 1.573 0 2.292-.337 2.657-.751.384-.435.558-1.15.558-2.361 0-1.14-.243-1.847-.705-2.319-.477-.488-1.319-.862-2.824-1.025-1.487-.161-2.192.138-2.533.529-.269.307-.437.808-.438 1.578v.021c0 .265.021.562.063.893Zm-1.626 0c.042-.331.063-.628.063-.894v-.02c-.001-.77-.169-1.271-.438-1.578-.341-.391-1.046-.69-2.533-.529-1.505.163-2.347.537-2.824 1.025-.462.472-.705 1.179-.705 2.319 0 1.211.175 1.926.558 2.361.365.414 1.084.751 2.657.751 1.21 0 1.902-.394 2.344-.938.475-.584.742-1.44.878-2.497Z"></path><path d="M14.5 14.25a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0v-2a1 1 0 0 1 1-1Zm-5 0a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0v-2a1 1 0 0 1 1-1Z"></path> </svg> <div> <div class="color-fg-default h4">GitHub Copilot</div> Enterprise-grade AI features </div> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;premium_support&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;premium_support_link_enterprise_navbar&quot;}" href="/premium-support"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-comment-discussion color-fg-subtle mr-3"> <path d="M1.75 1h12.5c.966 0 1.75.784 1.75 1.75v9.5A1.75 1.75 0 0 1 14.25 14H8.061l-2.574 2.573A1.458 1.458 0 0 1 3 15.543V14H1.75A1.75 1.75 0 0 1 0 12.25v-9.5C0 1.784.784 1 1.75 1ZM1.5 2.75v9.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-9.5a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25Z"></path><path d="M22.5 8.75a.25.25 0 0 0-.25-.25h-3.5a.75.75 0 0 1 0-1.5h3.5c.966 0 1.75.784 1.75 1.75v9.5A1.75 1.75 0 0 1 22.25 20H21v1.543a1.457 1.457 0 0 1-2.487 1.03L15.939 20H10.75A1.75 1.75 0 0 1 9 18.25v-1.465a.75.75 0 0 1 1.5 0v1.465c0 .138.112.25.25.25h5.5a.75.75 0 0 1 .53.22l2.72 2.72v-2.19a.75.75 0 0 1 .75-.75h2a.25.25 0 0 0 .25-.25v-9.5Z"></path> </svg> <div> <div class="color-fg-default h4">Premium Support</div> Enterprise-grade 24/7 support </div> </a></li> </ul> </div> </div> </div> </li> <li class="HeaderMenu-item position-relative flex-wrap flex-justify-between flex-items-center d-block d-lg-flex flex-lg-nowrap flex-lg-items-center js-details-container js-header-menu-item"> <a class="HeaderMenu-link no-underline px-0 px-lg-2 py-3 py-lg-2 d-block d-lg-inline-block" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;pricing&quot;,&quot;context&quot;:&quot;global&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;pricing_link_global_navbar&quot;}" href="https://github.com/pricing">Pricing</a> </li> </ul> </nav> <div class="d-flex flex-column flex-lg-row width-full flex-justify-end flex-lg-items-center text-center mt-3 mt-lg-0 text-lg-left ml-lg-3"> <qbsearch-input class="search-input" data-scope="repo:ampproject/amphtml" data-custom-scopes-path="/search/custom_scopes" data-delete-custom-scopes-csrf="34rQK3FOB-98LOpPnRdq8stWzrztXAbdiVrnmvU2ss-2dCd-ZRxU_xVavah6puiSjw5BicZ34bf0OQKeaLBa-Q" data-max-custom-scopes="10" data-header-redesign-enabled="false" data-initial-value="" data-blackbird-suggestions-path="/search/suggestions" data-jump-to-suggestions-path="/_graphql/GetSuggestedNavigationDestinations" data-current-repository="ampproject/amphtml" data-current-org="ampproject" data-current-owner="" data-logged-in="false" data-copilot-chat-enabled="false" data-nl-search-enabled="false" data-retain-scroll-position="true"> <div class="search-input-container search-with-dialog position-relative d-flex flex-row flex-items-center mr-4 rounded" data-action="click:qbsearch-input#searchInputContainerClicked" > <button type="button" class="header-search-button placeholder input-button form-control d-flex flex-1 flex-self-stretch flex-items-center no-wrap width-full py-0 pl-2 pr-0 text-left border-0 box-shadow-none" data-target="qbsearch-input.inputButton" aria-label="Search or jump to…" aria-haspopup="dialog" placeholder="Search or jump to..." data-hotkey=s,/ autocapitalize="off" data-analytics-event="{&quot;location&quot;:&quot;navbar&quot;,&quot;action&quot;:&quot;searchbar&quot;,&quot;context&quot;:&quot;global&quot;,&quot;tag&quot;:&quot;input&quot;,&quot;label&quot;:&quot;searchbar_input_global_navbar&quot;}" data-action="click:qbsearch-input#handleExpand" > <div class="mr-2 color-fg-muted"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-search"> <path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path> </svg> </div> <span class="flex-1" data-target="qbsearch-input.inputButtonText">Search or jump to...</span> <div class="d-flex" data-target="qbsearch-input.hotkeyIndicator"> <svg xmlns="http://www.w3.org/2000/svg" width="22" height="20" aria-hidden="true" class="mr-1"><path fill="none" stroke="#979A9C" opacity=".4" d="M3.5.5h12c1.7 0 3 1.3 3 3v13c0 1.7-1.3 3-3 3h-12c-1.7 0-3-1.3-3-3v-13c0-1.7 1.3-3 3-3z"></path><path fill="#979A9C" d="M11.8 6L8 15.1h-.9L10.8 6h1z"></path></svg> </div> </button> <input type="hidden" name="type" class="js-site-search-type-field"> <div class="Overlay--hidden " data-modal-dialog-overlay> <modal-dialog data-action="close:qbsearch-input#handleClose cancel:qbsearch-input#handleClose" data-target="qbsearch-input.searchSuggestionsDialog" role="dialog" id="search-suggestions-dialog" aria-modal="true" aria-labelledby="search-suggestions-dialog-header" data-view-component="true" class="Overlay Overlay--width-large Overlay--height-auto"> <h1 id="search-suggestions-dialog-header" class="sr-only">Search code, repositories, users, issues, pull requests...</h1> <div class="Overlay-body Overlay-body--paddingNone"> <div data-view-component="true"> <div class="search-suggestions position-fixed width-full color-shadow-large border color-fg-default color-bg-default overflow-hidden d-flex flex-column query-builder-container" style="border-radius: 12px;" data-target="qbsearch-input.queryBuilderContainer" hidden > <!-- '"` --><!-- </textarea></xmp> --></option></form><form id="query-builder-test-form" action="" accept-charset="UTF-8" method="get"> <query-builder data-target="qbsearch-input.queryBuilder" id="query-builder-query-builder-test" data-filter-key=":" data-view-component="true" class="QueryBuilder search-query-builder"> <div class="FormControl FormControl--fullWidth"> <label id="query-builder-test-label" for="query-builder-test" class="FormControl-label sr-only"> Search </label> <div class="QueryBuilder-StyledInput width-fit " data-target="query-builder.styledInput" > <span id="query-builder-test-leadingvisual-wrap" class="FormControl-input-leadingVisualWrap QueryBuilder-leadingVisualWrap"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-search FormControl-input-leadingVisual"> <path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path> </svg> </span> <div data-target="query-builder.styledInputContainer" class="QueryBuilder-StyledInputContainer"> <div aria-hidden="true" class="QueryBuilder-StyledInputContent" data-target="query-builder.styledInputContent" ></div> <div class="QueryBuilder-InputWrapper"> <div aria-hidden="true" class="QueryBuilder-Sizer" data-target="query-builder.sizer"></div> <input id="query-builder-test" name="query-builder-test" value="" autocomplete="off" type="text" role="combobox" spellcheck="false" aria-expanded="false" aria-describedby="validation-6cc01000-1858-4338-868e-035aea3f00d5" data-target="query-builder.input" data-action=" input:query-builder#inputChange blur:query-builder#inputBlur keydown:query-builder#inputKeydown focus:query-builder#inputFocus " data-view-component="true" class="FormControl-input QueryBuilder-Input FormControl-medium" /> </div> </div> <span class="sr-only" id="query-builder-test-clear">Clear</span> <button role="button" id="query-builder-test-clear-button" aria-labelledby="query-builder-test-clear query-builder-test-label" data-target="query-builder.clearButton" data-action=" click:query-builder#clear focus:query-builder#clearButtonFocus blur:query-builder#clearButtonBlur " variant="small" hidden="hidden" type="button" data-view-component="true" class="Button Button--iconOnly Button--invisible Button--medium mr-1 px-2 py-0 d-flex flex-items-center rounded-1 color-fg-muted"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x-circle-fill Button-visual"> <path d="M2.343 13.657A8 8 0 1 1 13.658 2.343 8 8 0 0 1 2.343 13.657ZM6.03 4.97a.751.751 0 0 0-1.042.018.751.751 0 0 0-.018 1.042L6.94 8 4.97 9.97a.749.749 0 0 0 .326 1.275.749.749 0 0 0 .734-.215L8 9.06l1.97 1.97a.749.749 0 0 0 1.275-.326.749.749 0 0 0-.215-.734L9.06 8l1.97-1.97a.749.749 0 0 0-.326-1.275.749.749 0 0 0-.734.215L8 6.94Z"></path> </svg> </button> </div> <template id="search-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-search"> <path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path> </svg> </template> <template id="code-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-code"> <path d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path> </svg> </template> <template id="file-code-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-file-code"> <path d="M4 1.75C4 .784 4.784 0 5.75 0h5.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v8.586A1.75 1.75 0 0 1 14.25 15h-9a.75.75 0 0 1 0-1.5h9a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 10 4.25V1.5H5.75a.25.25 0 0 0-.25.25v2.5a.75.75 0 0 1-1.5 0Zm1.72 4.97a.75.75 0 0 1 1.06 0l2 2a.75.75 0 0 1 0 1.06l-2 2a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734l1.47-1.47-1.47-1.47a.75.75 0 0 1 0-1.06ZM3.28 7.78 1.81 9.25l1.47 1.47a.751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018l-2-2a.75.75 0 0 1 0-1.06l2-2a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Zm8.22-6.218V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z"></path> </svg> </template> <template id="history-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-history"> <path d="m.427 1.927 1.215 1.215a8.002 8.002 0 1 1-1.6 5.685.75.75 0 1 1 1.493-.154 6.5 6.5 0 1 0 1.18-4.458l1.358 1.358A.25.25 0 0 1 3.896 6H.25A.25.25 0 0 1 0 5.75V2.104a.25.25 0 0 1 .427-.177ZM7.75 4a.75.75 0 0 1 .75.75v2.992l2.028.812a.75.75 0 0 1-.557 1.392l-2.5-1A.751.751 0 0 1 7 8.25v-3.5A.75.75 0 0 1 7.75 4Z"></path> </svg> </template> <template id="repo-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo"> <path d="M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 1 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5Zm10.5-1h-8a1 1 0 0 0-1 1v6.708A2.486 2.486 0 0 1 4.5 9h8ZM5 12.25a.25.25 0 0 1 .25-.25h3.5a.25.25 0 0 1 .25.25v3.25a.25.25 0 0 1-.4.2l-1.45-1.087a.249.249 0 0 0-.3 0L5.4 15.7a.25.25 0 0 1-.4-.2Z"></path> </svg> </template> <template id="bookmark-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-bookmark"> <path d="M3 2.75C3 1.784 3.784 1 4.75 1h6.5c.966 0 1.75.784 1.75 1.75v11.5a.75.75 0 0 1-1.227.579L8 11.722l-3.773 3.107A.751.751 0 0 1 3 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v9.91l3.023-2.489a.75.75 0 0 1 .954 0l3.023 2.49V2.75a.25.25 0 0 0-.25-.25Z"></path> </svg> </template> <template id="plus-circle-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-plus-circle"> <path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm7.25-3.25v2.5h2.5a.75.75 0 0 1 0 1.5h-2.5v2.5a.75.75 0 0 1-1.5 0v-2.5h-2.5a.75.75 0 0 1 0-1.5h2.5v-2.5a.75.75 0 0 1 1.5 0Z"></path> </svg> </template> <template id="circle-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-dot-fill"> <path d="M8 4a4 4 0 1 1 0 8 4 4 0 0 1 0-8Z"></path> </svg> </template> <template id="trash-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-trash"> <path d="M11 1.75V3h2.25a.75.75 0 0 1 0 1.5H2.75a.75.75 0 0 1 0-1.5H5V1.75C5 .784 5.784 0 6.75 0h2.5C10.216 0 11 .784 11 1.75ZM4.496 6.675l.66 6.6a.25.25 0 0 0 .249.225h5.19a.25.25 0 0 0 .249-.225l.66-6.6a.75.75 0 0 1 1.492.149l-.66 6.6A1.748 1.748 0 0 1 10.595 15h-5.19a1.75 1.75 0 0 1-1.741-1.575l-.66-6.6a.75.75 0 1 1 1.492-.15ZM6.5 1.75V3h3V1.75a.25.25 0 0 0-.25-.25h-2.5a.25.25 0 0 0-.25.25Z"></path> </svg> </template> <template id="team-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-people"> <path d="M2 5.5a3.5 3.5 0 1 1 5.898 2.549 5.508 5.508 0 0 1 3.034 4.084.75.75 0 1 1-1.482.235 4 4 0 0 0-7.9 0 .75.75 0 0 1-1.482-.236A5.507 5.507 0 0 1 3.102 8.05 3.493 3.493 0 0 1 2 5.5ZM11 4a3.001 3.001 0 0 1 2.22 5.018 5.01 5.01 0 0 1 2.56 3.012.749.749 0 0 1-.885.954.752.752 0 0 1-.549-.514 3.507 3.507 0 0 0-2.522-2.372.75.75 0 0 1-.574-.73v-.352a.75.75 0 0 1 .416-.672A1.5 1.5 0 0 0 11 5.5.75.75 0 0 1 11 4Zm-5.5-.5a2 2 0 1 0-.001 3.999A2 2 0 0 0 5.5 3.5Z"></path> </svg> </template> <template id="project-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-project"> <path d="M1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25V1.75C0 .784.784 0 1.75 0ZM1.5 1.75v12.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25ZM11.75 3a.75.75 0 0 1 .75.75v7.5a.75.75 0 0 1-1.5 0v-7.5a.75.75 0 0 1 .75-.75Zm-8.25.75a.75.75 0 0 1 1.5 0v5.5a.75.75 0 0 1-1.5 0ZM8 3a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 8 3Z"></path> </svg> </template> <template id="pencil-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-pencil"> <path d="M11.013 1.427a1.75 1.75 0 0 1 2.474 0l1.086 1.086a1.75 1.75 0 0 1 0 2.474l-8.61 8.61c-.21.21-.47.364-.756.445l-3.251.93a.75.75 0 0 1-.927-.928l.929-3.25c.081-.286.235-.547.445-.758l8.61-8.61Zm.176 4.823L9.75 4.81l-6.286 6.287a.253.253 0 0 0-.064.108l-.558 1.953 1.953-.558a.253.253 0 0 0 .108-.064Zm1.238-3.763a.25.25 0 0 0-.354 0L10.811 3.75l1.439 1.44 1.263-1.263a.25.25 0 0 0 0-.354Z"></path> </svg> </template> <template id="copilot-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copilot"> <path d="M7.998 15.035c-4.562 0-7.873-2.914-7.998-3.749V9.338c.085-.628.677-1.686 1.588-2.065.013-.07.024-.143.036-.218.029-.183.06-.384.126-.612-.201-.508-.254-1.084-.254-1.656 0-.87.128-1.769.693-2.484.579-.733 1.494-1.124 2.724-1.261 1.206-.134 2.262.034 2.944.765.05.053.096.108.139.165.044-.057.094-.112.143-.165.682-.731 1.738-.899 2.944-.765 1.23.137 2.145.528 2.724 1.261.566.715.693 1.614.693 2.484 0 .572-.053 1.148-.254 1.656.066.228.098.429.126.612.012.076.024.148.037.218.924.385 1.522 1.471 1.591 2.095v1.872c0 .766-3.351 3.795-8.002 3.795Zm0-1.485c2.28 0 4.584-1.11 5.002-1.433V7.862l-.023-.116c-.49.21-1.075.291-1.727.291-1.146 0-2.059-.327-2.71-.991A3.222 3.222 0 0 1 8 6.303a3.24 3.24 0 0 1-.544.743c-.65.664-1.563.991-2.71.991-.652 0-1.236-.081-1.727-.291l-.023.116v4.255c.419.323 2.722 1.433 5.002 1.433ZM6.762 2.83c-.193-.206-.637-.413-1.682-.297-1.019.113-1.479.404-1.713.7-.247.312-.369.789-.369 1.554 0 .793.129 1.171.308 1.371.162.181.519.379 1.442.379.853 0 1.339-.235 1.638-.54.315-.322.527-.827.617-1.553.117-.935-.037-1.395-.241-1.614Zm4.155-.297c-1.044-.116-1.488.091-1.681.297-.204.219-.359.679-.242 1.614.091.726.303 1.231.618 1.553.299.305.784.54 1.638.54.922 0 1.28-.198 1.442-.379.179-.2.308-.578.308-1.371 0-.765-.123-1.242-.37-1.554-.233-.296-.693-.587-1.713-.7Z"></path><path d="M6.25 9.037a.75.75 0 0 1 .75.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 .75-.75Zm4.25.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 1.5 0Z"></path> </svg> </template> <template id="copilot-error-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copilot-error"> <path d="M16 11.24c0 .112-.072.274-.21.467L13 9.688V7.862l-.023-.116c-.49.21-1.075.291-1.727.291-.198 0-.388-.009-.571-.029L6.833 5.226a4.01 4.01 0 0 0 .17-.782c.117-.935-.037-1.395-.241-1.614-.193-.206-.637-.413-1.682-.297-.683.076-1.115.231-1.395.415l-1.257-.91c.579-.564 1.413-.877 2.485-.996 1.206-.134 2.262.034 2.944.765.05.053.096.108.139.165.044-.057.094-.112.143-.165.682-.731 1.738-.899 2.944-.765 1.23.137 2.145.528 2.724 1.261.566.715.693 1.614.693 2.484 0 .572-.053 1.148-.254 1.656.066.228.098.429.126.612.012.076.024.148.037.218.924.385 1.522 1.471 1.591 2.095Zm-5.083-8.707c-1.044-.116-1.488.091-1.681.297-.204.219-.359.679-.242 1.614.091.726.303 1.231.618 1.553.299.305.784.54 1.638.54.922 0 1.28-.198 1.442-.379.179-.2.308-.578.308-1.371 0-.765-.123-1.242-.37-1.554-.233-.296-.693-.587-1.713-.7Zm2.511 11.074c-1.393.776-3.272 1.428-5.43 1.428-4.562 0-7.873-2.914-7.998-3.749V9.338c.085-.628.677-1.686 1.588-2.065.013-.07.024-.143.036-.218.029-.183.06-.384.126-.612-.18-.455-.241-.963-.252-1.475L.31 4.107A.747.747 0 0 1 0 3.509V3.49a.748.748 0 0 1 .625-.73c.156-.026.306.047.435.139l14.667 10.578a.592.592 0 0 1 .227.264.752.752 0 0 1 .046.249v.022a.75.75 0 0 1-1.19.596Zm-1.367-.991L5.635 7.964a5.128 5.128 0 0 1-.889.073c-.652 0-1.236-.081-1.727-.291l-.023.116v4.255c.419.323 2.722 1.433 5.002 1.433 1.539 0 3.089-.505 4.063-.934Z"></path> </svg> </template> <template id="workflow-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-workflow"> <path d="M0 1.75C0 .784.784 0 1.75 0h3.5C6.216 0 7 .784 7 1.75v3.5A1.75 1.75 0 0 1 5.25 7H4v4a1 1 0 0 0 1 1h4v-1.25C9 9.784 9.784 9 10.75 9h3.5c.966 0 1.75.784 1.75 1.75v3.5A1.75 1.75 0 0 1 14.25 16h-3.5A1.75 1.75 0 0 1 9 14.25v-.75H5A2.5 2.5 0 0 1 2.5 11V7h-.75A1.75 1.75 0 0 1 0 5.25Zm1.75-.25a.25.25 0 0 0-.25.25v3.5c0 .138.112.25.25.25h3.5a.25.25 0 0 0 .25-.25v-3.5a.25.25 0 0 0-.25-.25Zm9 9a.25.25 0 0 0-.25.25v3.5c0 .138.112.25.25.25h3.5a.25.25 0 0 0 .25-.25v-3.5a.25.25 0 0 0-.25-.25Z"></path> </svg> </template> <template id="book-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-book"> <path d="M0 1.75A.75.75 0 0 1 .75 1h4.253c1.227 0 2.317.59 3 1.501A3.743 3.743 0 0 1 11.006 1h4.245a.75.75 0 0 1 .75.75v10.5a.75.75 0 0 1-.75.75h-4.507a2.25 2.25 0 0 0-1.591.659l-.622.621a.75.75 0 0 1-1.06 0l-.622-.621A2.25 2.25 0 0 0 5.258 13H.75a.75.75 0 0 1-.75-.75Zm7.251 10.324.004-5.073-.002-2.253A2.25 2.25 0 0 0 5.003 2.5H1.5v9h3.757a3.75 3.75 0 0 1 1.994.574ZM8.755 4.75l-.004 7.322a3.752 3.752 0 0 1 1.992-.572H14.5v-9h-3.495a2.25 2.25 0 0 0-2.25 2.25Z"></path> </svg> </template> <template id="code-review-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-code-review"> <path d="M1.75 1h12.5c.966 0 1.75.784 1.75 1.75v8.5A1.75 1.75 0 0 1 14.25 13H8.061l-2.574 2.573A1.458 1.458 0 0 1 3 14.543V13H1.75A1.75 1.75 0 0 1 0 11.25v-8.5C0 1.784.784 1 1.75 1ZM1.5 2.75v8.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-8.5a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25Zm5.28 1.72a.75.75 0 0 1 0 1.06L5.31 7l1.47 1.47a.751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018l-2-2a.75.75 0 0 1 0-1.06l2-2a.75.75 0 0 1 1.06 0Zm2.44 0a.75.75 0 0 1 1.06 0l2 2a.75.75 0 0 1 0 1.06l-2 2a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L10.69 7 9.22 5.53a.75.75 0 0 1 0-1.06Z"></path> </svg> </template> <template id="codespaces-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-codespaces"> <path d="M0 11.25c0-.966.784-1.75 1.75-1.75h12.5c.966 0 1.75.784 1.75 1.75v3A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm2-9.5C2 .784 2.784 0 3.75 0h8.5C13.216 0 14 .784 14 1.75v5a1.75 1.75 0 0 1-1.75 1.75h-8.5A1.75 1.75 0 0 1 2 6.75Zm1.75-.25a.25.25 0 0 0-.25.25v5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-5a.25.25 0 0 0-.25-.25Zm-2 9.5a.25.25 0 0 0-.25.25v3c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-3a.25.25 0 0 0-.25-.25Z"></path><path d="M7 12.75a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75Zm-4 0a.75.75 0 0 1 .75-.75h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1-.75-.75Z"></path> </svg> </template> <template id="comment-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-comment"> <path d="M1 2.75C1 1.784 1.784 1 2.75 1h10.5c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0 1 13.25 12H9.06l-2.573 2.573A1.458 1.458 0 0 1 4 13.543V12H2.75A1.75 1.75 0 0 1 1 10.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h4.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path> </svg> </template> <template id="comment-discussion-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-comment-discussion"> <path d="M1.75 1h8.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 10.25 10H7.061l-2.574 2.573A1.458 1.458 0 0 1 2 11.543V10h-.25A1.75 1.75 0 0 1 0 8.25v-5.5C0 1.784.784 1 1.75 1ZM1.5 2.75v5.5c0 .138.112.25.25.25h1a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h3.5a.25.25 0 0 0 .25-.25v-5.5a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25Zm13 2a.25.25 0 0 0-.25-.25h-.5a.75.75 0 0 1 0-1.5h.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 14.25 12H14v1.543a1.458 1.458 0 0 1-2.487 1.03L9.22 12.28a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l2.22 2.22v-2.19a.75.75 0 0 1 .75-.75h1a.25.25 0 0 0 .25-.25Z"></path> </svg> </template> <template id="organization-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-organization"> <path d="M1.75 16A1.75 1.75 0 0 1 0 14.25V1.75C0 .784.784 0 1.75 0h8.5C11.216 0 12 .784 12 1.75v12.5c0 .085-.006.168-.018.25h2.268a.25.25 0 0 0 .25-.25V8.285a.25.25 0 0 0-.111-.208l-1.055-.703a.749.749 0 1 1 .832-1.248l1.055.703c.487.325.779.871.779 1.456v5.965A1.75 1.75 0 0 1 14.25 16h-3.5a.766.766 0 0 1-.197-.026c-.099.017-.2.026-.303.026h-3a.75.75 0 0 1-.75-.75V14h-1v1.25a.75.75 0 0 1-.75.75Zm-.25-1.75c0 .138.112.25.25.25H4v-1.25a.75.75 0 0 1 .75-.75h2.5a.75.75 0 0 1 .75.75v1.25h2.25a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25ZM3.75 6h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5ZM3 3.75A.75.75 0 0 1 3.75 3h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 3 3.75Zm4 3A.75.75 0 0 1 7.75 6h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 7 6.75ZM7.75 3h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5ZM3 9.75A.75.75 0 0 1 3.75 9h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 3 9.75ZM7.75 9h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5Z"></path> </svg> </template> <template id="rocket-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-rocket"> <path d="M14.064 0h.186C15.216 0 16 .784 16 1.75v.186a8.752 8.752 0 0 1-2.564 6.186l-.458.459c-.314.314-.641.616-.979.904v3.207c0 .608-.315 1.172-.833 1.49l-2.774 1.707a.749.749 0 0 1-1.11-.418l-.954-3.102a1.214 1.214 0 0 1-.145-.125L3.754 9.816a1.218 1.218 0 0 1-.124-.145L.528 8.717a.749.749 0 0 1-.418-1.11l1.71-2.774A1.748 1.748 0 0 1 3.31 4h3.204c.288-.338.59-.665.904-.979l.459-.458A8.749 8.749 0 0 1 14.064 0ZM8.938 3.623h-.002l-.458.458c-.76.76-1.437 1.598-2.02 2.5l-1.5 2.317 2.143 2.143 2.317-1.5c.902-.583 1.74-1.26 2.499-2.02l.459-.458a7.25 7.25 0 0 0 2.123-5.127V1.75a.25.25 0 0 0-.25-.25h-.186a7.249 7.249 0 0 0-5.125 2.123ZM3.56 14.56c-.732.732-2.334 1.045-3.005 1.148a.234.234 0 0 1-.201-.064.234.234 0 0 1-.064-.201c.103-.671.416-2.273 1.15-3.003a1.502 1.502 0 1 1 2.12 2.12Zm6.94-3.935c-.088.06-.177.118-.266.175l-2.35 1.521.548 1.783 1.949-1.2a.25.25 0 0 0 .119-.213ZM3.678 8.116 5.2 5.766c.058-.09.117-.178.176-.266H3.309a.25.25 0 0 0-.213.119l-1.2 1.95ZM12 5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path> </svg> </template> <template id="shield-check-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-shield-check"> <path d="m8.533.133 5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667l5.25-1.68a1.748 1.748 0 0 1 1.066 0Zm-.61 1.429.001.001-5.25 1.68a.251.251 0 0 0-.174.237V7c0 1.36.275 2.666 1.057 3.859.784 1.194 2.121 2.342 4.366 3.298a.196.196 0 0 0 .154 0c2.245-.957 3.582-2.103 4.366-3.297C13.225 9.666 13.5 8.358 13.5 7V3.48a.25.25 0 0 0-.174-.238l-5.25-1.68a.25.25 0 0 0-.153 0ZM11.28 6.28l-3.5 3.5a.75.75 0 0 1-1.06 0l-1.5-1.5a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l.97.97 2.97-2.97a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path> </svg> </template> <template id="heart-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-heart"> <path d="m8 14.25.345.666a.75.75 0 0 1-.69 0l-.008-.004-.018-.01a7.152 7.152 0 0 1-.31-.17 22.055 22.055 0 0 1-3.434-2.414C2.045 10.731 0 8.35 0 5.5 0 2.836 2.086 1 4.25 1 5.797 1 7.153 1.802 8 3.02 8.847 1.802 10.203 1 11.75 1 13.914 1 16 2.836 16 5.5c0 2.85-2.045 5.231-3.885 6.818a22.066 22.066 0 0 1-3.744 2.584l-.018.01-.006.003h-.002ZM4.25 2.5c-1.336 0-2.75 1.164-2.75 3 0 2.15 1.58 4.144 3.365 5.682A20.58 20.58 0 0 0 8 13.393a20.58 20.58 0 0 0 3.135-2.211C12.92 9.644 14.5 7.65 14.5 5.5c0-1.836-1.414-3-2.75-3-1.373 0-2.609.986-3.029 2.456a.749.749 0 0 1-1.442 0C6.859 3.486 5.623 2.5 4.25 2.5Z"></path> </svg> </template> <template id="server-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-server"> <path d="M1.75 1h12.5c.966 0 1.75.784 1.75 1.75v4c0 .372-.116.717-.314 1 .198.283.314.628.314 1v4a1.75 1.75 0 0 1-1.75 1.75H1.75A1.75 1.75 0 0 1 0 12.75v-4c0-.358.109-.707.314-1a1.739 1.739 0 0 1-.314-1v-4C0 1.784.784 1 1.75 1ZM1.5 2.75v4c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-4a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25Zm.25 5.75a.25.25 0 0 0-.25.25v4c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-4a.25.25 0 0 0-.25-.25ZM7 4.75A.75.75 0 0 1 7.75 4h4.5a.75.75 0 0 1 0 1.5h-4.5A.75.75 0 0 1 7 4.75ZM7.75 10h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1 0-1.5ZM3 4.75A.75.75 0 0 1 3.75 4h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 3 4.75ZM3.75 10h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5Z"></path> </svg> </template> <template id="globe-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-globe"> <path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM5.78 8.75a9.64 9.64 0 0 0 1.363 4.177c.255.426.542.832.857 1.215.245-.296.551-.705.857-1.215A9.64 9.64 0 0 0 10.22 8.75Zm4.44-1.5a9.64 9.64 0 0 0-1.363-4.177c-.307-.51-.612-.919-.857-1.215a9.927 9.927 0 0 0-.857 1.215A9.64 9.64 0 0 0 5.78 7.25Zm-5.944 1.5H1.543a6.507 6.507 0 0 0 4.666 5.5c-.123-.181-.24-.365-.352-.552-.715-1.192-1.437-2.874-1.581-4.948Zm-2.733-1.5h2.733c.144-2.074.866-3.756 1.58-4.948.12-.197.237-.381.353-.552a6.507 6.507 0 0 0-4.666 5.5Zm10.181 1.5c-.144 2.074-.866 3.756-1.58 4.948-.12.197-.237.381-.353.552a6.507 6.507 0 0 0 4.666-5.5Zm2.733-1.5a6.507 6.507 0 0 0-4.666-5.5c.123.181.24.365.353.552.714 1.192 1.436 2.874 1.58 4.948Z"></path> </svg> </template> <template id="issue-opened-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-issue-opened"> <path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path> </svg> </template> <template id="device-mobile-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-device-mobile"> <path d="M3.75 0h8.5C13.216 0 14 .784 14 1.75v12.5A1.75 1.75 0 0 1 12.25 16h-8.5A1.75 1.75 0 0 1 2 14.25V1.75C2 .784 2.784 0 3.75 0ZM3.5 1.75v12.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25ZM8 13a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path> </svg> </template> <template id="package-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-package"> <path d="m8.878.392 5.25 3.045c.54.314.872.89.872 1.514v6.098a1.75 1.75 0 0 1-.872 1.514l-5.25 3.045a1.75 1.75 0 0 1-1.756 0l-5.25-3.045A1.75 1.75 0 0 1 1 11.049V4.951c0-.624.332-1.201.872-1.514L7.122.392a1.75 1.75 0 0 1 1.756 0ZM7.875 1.69l-4.63 2.685L8 7.133l4.755-2.758-4.63-2.685a.248.248 0 0 0-.25 0ZM2.5 5.677v5.372c0 .09.047.171.125.216l4.625 2.683V8.432Zm6.25 8.271 4.625-2.683a.25.25 0 0 0 .125-.216V5.677L8.75 8.432Z"></path> </svg> </template> <template id="credit-card-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-credit-card"> <path d="M10.75 9a.75.75 0 0 0 0 1.5h1.5a.75.75 0 0 0 0-1.5h-1.5Z"></path><path d="M0 3.75C0 2.784.784 2 1.75 2h12.5c.966 0 1.75.784 1.75 1.75v8.5A1.75 1.75 0 0 1 14.25 14H1.75A1.75 1.75 0 0 1 0 12.25ZM14.5 6.5h-13v5.75c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25Zm0-2.75a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25V5h13Z"></path> </svg> </template> <template id="play-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-play"> <path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm4.879-2.773 4.264 2.559a.25.25 0 0 1 0 .428l-4.264 2.559A.25.25 0 0 1 6 10.559V5.442a.25.25 0 0 1 .379-.215Z"></path> </svg> </template> <template id="gift-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-gift"> <path d="M2 2.75A2.75 2.75 0 0 1 4.75 0c.983 0 1.873.42 2.57 1.232.268.318.497.668.68 1.042.183-.375.411-.725.68-1.044C9.376.42 10.266 0 11.25 0a2.75 2.75 0 0 1 2.45 4h.55c.966 0 1.75.784 1.75 1.75v2c0 .698-.409 1.301-1 1.582v4.918A1.75 1.75 0 0 1 13.25 16H2.75A1.75 1.75 0 0 1 1 14.25V9.332C.409 9.05 0 8.448 0 7.75v-2C0 4.784.784 4 1.75 4h.55c-.192-.375-.3-.8-.3-1.25ZM7.25 9.5H2.5v4.75c0 .138.112.25.25.25h4.5Zm1.5 0v5h4.5a.25.25 0 0 0 .25-.25V9.5Zm0-4V8h5.5a.25.25 0 0 0 .25-.25v-2a.25.25 0 0 0-.25-.25Zm-7 0a.25.25 0 0 0-.25.25v2c0 .138.112.25.25.25h5.5V5.5h-5.5Zm3-4a1.25 1.25 0 0 0 0 2.5h2.309c-.233-.818-.542-1.401-.878-1.793-.43-.502-.915-.707-1.431-.707ZM8.941 4h2.309a1.25 1.25 0 0 0 0-2.5c-.516 0-1 .205-1.43.707-.337.392-.646.975-.879 1.793Z"></path> </svg> </template> <template id="code-square-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-code-square"> <path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25Zm7.47 3.97a.75.75 0 0 1 1.06 0l2 2a.75.75 0 0 1 0 1.06l-2 2a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L10.69 8 9.22 6.53a.75.75 0 0 1 0-1.06ZM6.78 6.53 5.31 8l1.47 1.47a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215l-2-2a.75.75 0 0 1 0-1.06l2-2a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path> </svg> </template> <template id="device-desktop-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-device-desktop"> <path d="M14.25 1c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0 1 14.25 12h-3.727c.099 1.041.52 1.872 1.292 2.757A.752.752 0 0 1 11.25 16h-6.5a.75.75 0 0 1-.565-1.243c.772-.885 1.192-1.716 1.292-2.757H1.75A1.75 1.75 0 0 1 0 10.25v-7.5C0 1.784.784 1 1.75 1ZM1.75 2.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25ZM9.018 12H6.982a5.72 5.72 0 0 1-.765 2.5h3.566a5.72 5.72 0 0 1-.765-2.5Z"></path> </svg> </template> <div class="position-relative"> <ul role="listbox" class="ActionListWrap QueryBuilder-ListWrap" aria-label="Suggestions" data-action=" combobox-commit:query-builder#comboboxCommit mousedown:query-builder#resultsMousedown " data-target="query-builder.resultsList" data-persist-list=false id="query-builder-test-results" ></ul> </div> <div class="FormControl-inlineValidation" id="validation-6cc01000-1858-4338-868e-035aea3f00d5" hidden="hidden"> <span class="FormControl-inlineValidation--visual"> <svg aria-hidden="true" height="12" viewBox="0 0 12 12" version="1.1" width="12" data-view-component="true" class="octicon octicon-alert-fill"> <path d="M4.855.708c.5-.896 1.79-.896 2.29 0l4.675 8.351a1.312 1.312 0 0 1-1.146 1.954H1.33A1.313 1.313 0 0 1 .183 9.058ZM7 7V3H5v4Zm-1 3a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z"></path> </svg> </span> <span></span> </div> </div> <div data-target="query-builder.screenReaderFeedback" aria-live="polite" aria-atomic="true" class="sr-only"></div> </query-builder></form> <div class="d-flex flex-row color-fg-muted px-3 text-small color-bg-default search-feedback-prompt"> <a target="_blank" href="https://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax" data-view-component="true" class="Link color-fg-accent text-normal ml-2">Search syntax tips</a> <div class="d-flex flex-1"></div> </div> </div> </div> </div> </modal-dialog></div> </div> <div data-action="click:qbsearch-input#retract" class="dark-backdrop position-fixed" hidden data-target="qbsearch-input.darkBackdrop"></div> <div class="color-fg-default"> <dialog-helper> <dialog data-target="qbsearch-input.feedbackDialog" data-action="close:qbsearch-input#handleDialogClose cancel:qbsearch-input#handleDialogClose" id="feedback-dialog" aria-modal="true" aria-labelledby="feedback-dialog-title" aria-describedby="feedback-dialog-description" data-view-component="true" class="Overlay Overlay-whenNarrow Overlay--size-medium Overlay--motion-scaleFade Overlay--disableScroll"> <div data-view-component="true" class="Overlay-header"> <div class="Overlay-headerContentWrap"> <div class="Overlay-titleWrap"> <h1 class="Overlay-title " id="feedback-dialog-title"> Provide feedback </h1> </div> <div class="Overlay-actionWrap"> <button data-close-dialog-id="feedback-dialog" aria-label="Close" type="button" data-view-component="true" class="close-button Overlay-closeButton"><svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x"> <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path> </svg></button> </div> </div> </div> <scrollable-region data-labelled-by="feedback-dialog-title"> <div data-view-component="true" class="Overlay-body"> <!-- '"` --><!-- </textarea></xmp> --></option></form><form id="code-search-feedback-form" data-turbo="false" action="/search/feedback" accept-charset="UTF-8" method="post"><input type="hidden" data-csrf="true" name="authenticity_token" value="SwxnVcndO970kxiQAmP3yMiRpPKL4PJ+rMCq/gke413g2ItYUmVzjF9aymlAfPyuxSmTdIiZVxc1SKH2s6Cn8g==" /> <p>We read every piece of feedback, and take your input very seriously.</p> <textarea name="feedback" class="form-control width-full mb-2" style="height: 120px" id="feedback"></textarea> <input name="include_email" id="include_email" aria-label="Include my email address so I can be contacted" class="form-control mr-2" type="checkbox"> <label for="include_email" style="font-weight: normal">Include my email address so I can be contacted</label> </form></div> </scrollable-region> <div data-view-component="true" class="Overlay-footer Overlay-footer--alignEnd"> <button data-close-dialog-id="feedback-dialog" type="button" data-view-component="true" class="btn"> Cancel </button> <button form="code-search-feedback-form" data-action="click:qbsearch-input#submitFeedback" type="submit" data-view-component="true" class="btn-primary btn"> Submit feedback </button> </div> </dialog></dialog-helper> <custom-scopes data-target="qbsearch-input.customScopesManager"> <dialog-helper> <dialog data-target="custom-scopes.customScopesModalDialog" data-action="close:qbsearch-input#handleDialogClose cancel:qbsearch-input#handleDialogClose" id="custom-scopes-dialog" aria-modal="true" aria-labelledby="custom-scopes-dialog-title" aria-describedby="custom-scopes-dialog-description" data-view-component="true" class="Overlay Overlay-whenNarrow Overlay--size-medium Overlay--motion-scaleFade Overlay--disableScroll"> <div data-view-component="true" class="Overlay-header Overlay-header--divided"> <div class="Overlay-headerContentWrap"> <div class="Overlay-titleWrap"> <h1 class="Overlay-title " id="custom-scopes-dialog-title"> Saved searches </h1> <h2 id="custom-scopes-dialog-description" class="Overlay-description">Use saved searches to filter your results more quickly</h2> </div> <div class="Overlay-actionWrap"> <button data-close-dialog-id="custom-scopes-dialog" aria-label="Close" type="button" data-view-component="true" class="close-button Overlay-closeButton"><svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x"> <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path> </svg></button> </div> </div> </div> <scrollable-region data-labelled-by="custom-scopes-dialog-title"> <div data-view-component="true" class="Overlay-body"> <div data-target="custom-scopes.customScopesModalDialogFlash"></div> <div hidden class="create-custom-scope-form" data-target="custom-scopes.createCustomScopeForm"> <!-- '"` --><!-- </textarea></xmp> --></option></form><form id="custom-scopes-dialog-form" data-turbo="false" action="/search/custom_scopes" accept-charset="UTF-8" method="post"><input type="hidden" data-csrf="true" name="authenticity_token" value="nFUPJo8Gb3ney5rbpJqV4kb7nm6TM4VkyIIv1m6tsSvuJxayP4USg+/LGDQV/H15qwWENMqO2rwMwcYQKCuTfg==" /> <div data-target="custom-scopes.customScopesModalDialogFlash"></div> <input type="hidden" id="custom_scope_id" name="custom_scope_id" data-target="custom-scopes.customScopesIdField"> <div class="form-group"> <label for="custom_scope_name">Name</label> <auto-check src="/search/custom_scopes/check_name" required only-validate-on-blur="false"> <input type="text" name="custom_scope_name" id="custom_scope_name" data-target="custom-scopes.customScopesNameField" class="form-control" autocomplete="off" placeholder="github-ruby" required maxlength="50"> <input type="hidden" data-csrf="true" value="zPFawUphx9MXOSys/oxCSqkfXmRQFmJCP10wMbpdHJjV9AHKBu5ZV2qfkcfAfamUdPm0EHJ0+SFL+HdL15RtOw==" /> </auto-check> </div> <div class="form-group"> <label for="custom_scope_query">Query</label> <input type="text" name="custom_scope_query" id="custom_scope_query" data-target="custom-scopes.customScopesQueryField" class="form-control" autocomplete="off" placeholder="(repo:mona/a OR repo:mona/b) AND lang:python" required maxlength="500"> </div> <p class="text-small color-fg-muted"> To see all available qualifiers, see our <a class="Link--inTextBlock" href="https://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax">documentation</a>. </p> </form> </div> <div data-target="custom-scopes.manageCustomScopesForm"> <div data-target="custom-scopes.list"></div> </div> </div> </scrollable-region> <div data-view-component="true" class="Overlay-footer Overlay-footer--alignEnd Overlay-footer--divided"> <button data-action="click:custom-scopes#customScopesCancel" type="button" data-view-component="true" class="btn"> Cancel </button> <button form="custom-scopes-dialog-form" data-action="click:custom-scopes#customScopesSubmit" data-target="custom-scopes.customScopesSubmitButton" type="submit" data-view-component="true" class="btn-primary btn"> Create saved search </button> </div> </dialog></dialog-helper> </custom-scopes> </div> </qbsearch-input> <div class="position-relative HeaderMenu-link-wrap d-lg-inline-block"> <a href="/login?return_to=https%3A%2F%2Fgithub.com%2Fampproject%2Famphtml%2Fblob%2Fmain%2Fextensions%2Famp-a4a%2Frtc-documentation.md" class="HeaderMenu-link HeaderMenu-link--sign-in HeaderMenu-button flex-shrink-0 no-underline d-none d-lg-inline-flex border border-lg-0 rounded rounded-lg-0 px-2 py-1" style="margin-left: 12px;" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header menu&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/ampproject/amphtml/blob/main/extensions/amp-a4a/rtc-documentation.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="32cb0e328f9c6ea29ab66592e3cf515810bd8783fd8fecea3ff1753a8d1aba1c" data-analytics-event="{&quot;category&quot;:&quot;Marketing nav&quot;,&quot;action&quot;:&quot;click to go to homepage&quot;,&quot;label&quot;:&quot;ref_page:Marketing;ref_cta:Sign in;ref_loc:Header&quot;}" > Sign in </a> </div> <a href="/signup?ref_cta=Sign+up&amp;ref_loc=header+logged+out&amp;ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fblob%2Fshow&amp;source=header-repo&amp;source_repo=ampproject%2Famphtml" class="HeaderMenu-link HeaderMenu-link--sign-up HeaderMenu-button flex-shrink-0 d-flex d-lg-inline-flex no-underline border color-border-default rounded px-2 py-1" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header menu&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/ampproject/amphtml/blob/main/extensions/amp-a4a/rtc-documentation.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="32cb0e328f9c6ea29ab66592e3cf515810bd8783fd8fecea3ff1753a8d1aba1c" data-analytics-event="{&quot;category&quot;:&quot;Sign up&quot;,&quot;action&quot;:&quot;click to sign up for account&quot;,&quot;label&quot;:&quot;ref_page:/&lt;user-name&gt;/&lt;repo-name&gt;/blob/show;ref_cta:Sign up;ref_loc:header logged out&quot;}" > Sign up </a> <button type="button" class="sr-only js-header-menu-focus-trap d-block d-lg-none">Reseting focus</button> </div> </div> </div> </div> </header> <div hidden="hidden" data-view-component="true" class="js-stale-session-flash stale-session-flash flash flash-warn flash-full"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert"> <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path> </svg> <span class="js-stale-session-flash-signed-in" hidden>You signed in with another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span> <span class="js-stale-session-flash-signed-out" hidden>You signed out in another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span> <span class="js-stale-session-flash-switched" hidden>You switched accounts on another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span> <button id="icon-button-f5f8bd4f-35cb-42f3-b402-9b80288d8394" aria-labelledby="tooltip-e6585987-273c-4c07-bf02-8dd0ef305d85" type="button" data-view-component="true" class="Button Button--iconOnly Button--invisible Button--medium flash-close js-flash-close"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x Button-visual"> <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path> </svg> </button><tool-tip id="tooltip-e6585987-273c-4c07-bf02-8dd0ef305d85" for="icon-button-f5f8bd4f-35cb-42f3-b402-9b80288d8394" popover="manual" data-direction="s" data-type="label" data-view-component="true" class="sr-only position-absolute">Dismiss alert</tool-tip> </div> </div> <div id="start-of-content" class="show-on-focus"></div> <div id="js-flash-container" class="flash-container" data-turbo-replace> <template class="js-flash-template"> <div class="flash flash-full {{ className }}"> <div > <button autofocus class="flash-close js-flash-close" type="button" aria-label="Dismiss this message"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x"> <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path> </svg> </button> <div aria-atomic="true" role="alert" class="js-flash-alert"> <div>{{ message }}</div> </div> </div> </div> </template> </div> <div class="application-main " data-commit-hovercards-enabled data-discussion-hovercards-enabled data-issue-and-pr-hovercards-enabled data-project-hovercards-enabled > <div itemscope itemtype="http://schema.org/SoftwareSourceCode" class=""> <main id="js-repo-pjax-container" > <div id="repository-container-header" class="pt-3 hide-full-screen" style="background-color: var(--page-header-bgColor, var(--color-page-header-bg));" data-turbo-replace> <div class="d-flex flex-nowrap flex-justify-end mb-3 px-3 px-lg-5" style="gap: 1rem;"> <div class="flex-auto min-width-0 width-fit"> <div class=" d-flex flex-wrap flex-items-center wb-break-word f3 text-normal"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo color-fg-muted mr-2"> <path d="M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 1 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5Zm10.5-1h-8a1 1 0 0 0-1 1v6.708A2.486 2.486 0 0 1 4.5 9h8ZM5 12.25a.25.25 0 0 1 .25-.25h3.5a.25.25 0 0 1 .25.25v3.25a.25.25 0 0 1-.4.2l-1.45-1.087a.249.249 0 0 0-.3 0L5.4 15.7a.25.25 0 0 1-.4-.2Z"></path> </svg> <span class="author flex-self-stretch" itemprop="author"> <a class="url fn" rel="author" data-hovercard-type="organization" data-hovercard-url="/orgs/ampproject/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="/ampproject"> ampproject </a> </span> <span class="mx-1 flex-self-stretch color-fg-muted">/</span> <strong itemprop="name" class="mr-2 flex-self-stretch"> <a data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" href="/ampproject/amphtml">amphtml</a> </strong> <span></span><span class="Label Label--secondary v-align-middle mr-1">Public</span> </div> </div> <div id="repository-details-container" class="flex-shrink-0" data-turbo-replace style="max-width: 70%;"> <ul class="pagehead-actions flex-shrink-0 d-none d-md-inline" style="padding: 2px 0;"> <li> <a href="/login?return_to=%2Fampproject%2Famphtml" rel="nofollow" id="repository-details-watch-button" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;notification subscription menu watch&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/ampproject/amphtml/blob/main/extensions/amp-a4a/rtc-documentation.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="92cb937294d1d7719b5ad87cea07f1f8fc02400f08a4aa9340fef49c0515469c" aria-label="You must be signed in to change notification settings" data-view-component="true" class="btn-sm btn"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-bell mr-2"> <path d="M8 16a2 2 0 0 0 1.985-1.75c.017-.137-.097-.25-.235-.25h-3.5c-.138 0-.252.113-.235.25A2 2 0 0 0 8 16ZM3 5a5 5 0 0 1 10 0v2.947c0 .05.015.098.042.139l1.703 2.555A1.519 1.519 0 0 1 13.482 13H2.518a1.516 1.516 0 0 1-1.263-2.36l1.703-2.554A.255.255 0 0 0 3 7.947Zm5-3.5A3.5 3.5 0 0 0 4.5 5v2.947c0 .346-.102.683-.294.97l-1.703 2.556a.017.017 0 0 0-.003.01l.001.006c0 .002.002.004.004.006l.006.004.007.001h10.964l.007-.001.006-.004.004-.006.001-.007a.017.017 0 0 0-.003-.01l-1.703-2.554a1.745 1.745 0 0 1-.294-.97V5A3.5 3.5 0 0 0 8 1.5Z"></path> </svg>Notifications </a> <tool-tip id="tooltip-956194b6-dbc8-48a8-adba-30eccd015a8f" for="repository-details-watch-button" popover="manual" data-direction="s" data-type="description" data-view-component="true" class="sr-only position-absolute">You must be signed in to change notification settings</tool-tip> </li> <li> <a icon="repo-forked" id="fork-button" href="/login?return_to=%2Fampproject%2Famphtml" rel="nofollow" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;repo details fork button&quot;,&quot;repository_id&quot;:41766002,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/ampproject/amphtml/blob/main/extensions/amp-a4a/rtc-documentation.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="41c2015852b902c3fad6613cf4edbc593753f58cf5d538bc7ad1c56ecf017de9" data-view-component="true" class="btn-sm btn"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo-forked mr-2"> <path d="M5 5.372v.878c0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75v-.878a2.25 2.25 0 1 1 1.5 0v.878a2.25 2.25 0 0 1-2.25 2.25h-1.5v2.128a2.251 2.251 0 1 1-1.5 0V8.5h-1.5A2.25 2.25 0 0 1 3.5 6.25v-.878a2.25 2.25 0 1 1 1.5 0ZM5 3.25a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Zm6.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm-3 8.75a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Z"></path> </svg>Fork <span id="repo-network-counter" data-pjax-replace="true" data-turbo-replace="true" title="3,907" data-view-component="true" class="Counter">3.9k</span> </a> </li> <li> <div data-view-component="true" class="BtnGroup d-flex"> <a href="/login?return_to=%2Fampproject%2Famphtml" rel="nofollow" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;star button&quot;,&quot;repository_id&quot;:41766002,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/ampproject/amphtml/blob/main/extensions/amp-a4a/rtc-documentation.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="cdbc8f2afbc6f3270e8779954269fb8f72d9b654b69e856d88763ba90f583419" aria-label="You must be signed in to star a repository" data-view-component="true" class="tooltipped tooltipped-sw btn-sm btn"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-star v-align-text-bottom d-inline-block mr-2"> <path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694Z"></path> </svg><span data-view-component="true" class="d-inline"> Star </span> <span id="repo-stars-counter-star" aria-label="14900 users starred this repository" data-singular-suffix="user starred this repository" data-plural-suffix="users starred this repository" data-turbo-replace="true" title="14,900" data-view-component="true" class="Counter js-social-count">14.9k</span> </a></div> </li> </ul> </div> </div> <div id="responsive-meta-container" data-turbo-replace> </div> <nav data-pjax="#js-repo-pjax-container" aria-label="Repository" data-view-component="true" class="js-repo-nav js-sidenav-container-pjax js-responsive-underlinenav overflow-hidden UnderlineNav px-3 px-md-4 px-lg-5"> <ul data-view-component="true" class="UnderlineNav-body list-style-none"> <li data-view-component="true" class="d-inline-flex"> <a id="code-tab" href="/ampproject/amphtml" data-tab-item="i0code-tab" data-selected-links="repo_source repo_downloads repo_commits repo_releases repo_tags repo_branches repo_packages repo_deployments repo_attestations /ampproject/amphtml" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g c" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Code&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" aria-current="page" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item selected"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-code UnderlineNav-octicon d-none d-sm-inline"> <path d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path> </svg> <span data-content="Code">Code</span> <span id="code-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="Not available" data-view-component="true" class="Counter"></span> </a></li> <li data-view-component="true" class="d-inline-flex"> <a id="issues-tab" href="/ampproject/amphtml/issues" data-tab-item="i1issues-tab" data-selected-links="repo_issues repo_labels repo_milestones /ampproject/amphtml/issues" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g i" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Issues&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-issue-opened UnderlineNav-octicon d-none d-sm-inline"> <path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path> </svg> <span data-content="Issues">Issues</span> <span id="issues-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="905" data-view-component="true" class="Counter">905</span> </a></li> <li data-view-component="true" class="d-inline-flex"> <a id="pull-requests-tab" href="/ampproject/amphtml/pulls" data-tab-item="i2pull-requests-tab" data-selected-links="repo_pulls checks /ampproject/amphtml/pulls" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g p" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Pull requests&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-git-pull-request UnderlineNav-octicon d-none d-sm-inline"> <path d="M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25Zm5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354ZM3.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm0 9.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm8.25.75a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Z"></path> </svg> <span data-content="Pull requests">Pull requests</span> <span id="pull-requests-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="79" data-view-component="true" class="Counter">79</span> </a></li> <li data-view-component="true" class="d-inline-flex"> <a id="actions-tab" href="/ampproject/amphtml/actions" data-tab-item="i3actions-tab" data-selected-links="repo_actions /ampproject/amphtml/actions" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g a" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Actions&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-play UnderlineNav-octicon d-none d-sm-inline"> <path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm4.879-2.773 4.264 2.559a.25.25 0 0 1 0 .428l-4.264 2.559A.25.25 0 0 1 6 10.559V5.442a.25.25 0 0 1 .379-.215Z"></path> </svg> <span data-content="Actions">Actions</span> <span id="actions-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="Not available" data-view-component="true" class="Counter"></span> </a></li> <li data-view-component="true" class="d-inline-flex"> <a id="projects-tab" href="/ampproject/amphtml/projects" data-tab-item="i4projects-tab" data-selected-links="repo_projects new_repo_project repo_project /ampproject/amphtml/projects" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g b" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Projects&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-table UnderlineNav-octicon d-none d-sm-inline"> <path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25ZM6.5 6.5v8h7.75a.25.25 0 0 0 .25-.25V6.5Zm8-1.5V1.75a.25.25 0 0 0-.25-.25H6.5V5Zm-13 1.5v7.75c0 .138.112.25.25.25H5v-8ZM5 5V1.5H1.75a.25.25 0 0 0-.25.25V5Z"></path> </svg> <span data-content="Projects">Projects</span> <span id="projects-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="1" data-view-component="true" class="Counter">1</span> </a></li> <li data-view-component="true" class="d-inline-flex"> <a id="security-tab" href="/ampproject/amphtml/security" data-tab-item="i5security-tab" data-selected-links="security overview alerts policy token_scanning code_scanning /ampproject/amphtml/security" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g s" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Security&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-shield UnderlineNav-octicon d-none d-sm-inline"> <path d="M7.467.133a1.748 1.748 0 0 1 1.066 0l5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667Zm.61 1.429a.25.25 0 0 0-.153 0l-5.25 1.68a.25.25 0 0 0-.174.238V7c0 1.358.275 2.666 1.057 3.86.784 1.194 2.121 2.34 4.366 3.297a.196.196 0 0 0 .154 0c2.245-.956 3.582-2.104 4.366-3.298C13.225 9.666 13.5 8.36 13.5 7V3.48a.251.251 0 0 0-.174-.237l-5.25-1.68ZM8.75 4.75v3a.75.75 0 0 1-1.5 0v-3a.75.75 0 0 1 1.5 0ZM9 10.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path> </svg> <span data-content="Security">Security</span> <include-fragment src="/ampproject/amphtml/security/overall-count" accept="text/fragment+html"></include-fragment> </a></li> <li data-view-component="true" class="d-inline-flex"> <a id="insights-tab" href="/ampproject/amphtml/pulse" data-tab-item="i6insights-tab" data-selected-links="repo_graphs repo_contributors dependency_graph dependabot_updates pulse people community /ampproject/amphtml/pulse" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Insights&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-graph UnderlineNav-octicon d-none d-sm-inline"> <path d="M1.5 1.75V13.5h13.75a.75.75 0 0 1 0 1.5H.75a.75.75 0 0 1-.75-.75V1.75a.75.75 0 0 1 1.5 0Zm14.28 2.53-5.25 5.25a.75.75 0 0 1-1.06 0L7 7.06 4.28 9.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.25-3.25a.75.75 0 0 1 1.06 0L10 7.94l4.72-4.72a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path> </svg> <span data-content="Insights">Insights</span> <span id="insights-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="Not available" data-view-component="true" class="Counter"></span> </a></li> </ul> <div style="visibility:hidden;" data-view-component="true" class="UnderlineNav-actions js-responsive-underlinenav-overflow position-absolute pr-3 pr-md-4 pr-lg-5 right-0"> <action-menu data-select-variant="none" data-view-component="true"> <focus-group direction="vertical" mnemonics retain> <button id="action-menu-71ffe330-c9a5-43eb-86da-ac681a060a20-button" popovertarget="action-menu-71ffe330-c9a5-43eb-86da-ac681a060a20-overlay" aria-controls="action-menu-71ffe330-c9a5-43eb-86da-ac681a060a20-list" aria-haspopup="true" aria-labelledby="tooltip-25bf36bc-70ae-4348-9f86-6d9985535951" type="button" data-view-component="true" class="Button Button--iconOnly Button--secondary Button--medium UnderlineNav-item"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-kebab-horizontal Button-visual"> <path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path> </svg> </button><tool-tip id="tooltip-25bf36bc-70ae-4348-9f86-6d9985535951" for="action-menu-71ffe330-c9a5-43eb-86da-ac681a060a20-button" popover="manual" data-direction="s" data-type="label" data-view-component="true" class="sr-only position-absolute">Additional navigation options</tool-tip> <anchored-position data-target="action-menu.overlay" id="action-menu-71ffe330-c9a5-43eb-86da-ac681a060a20-overlay" anchor="action-menu-71ffe330-c9a5-43eb-86da-ac681a060a20-button" align="start" side="outside-bottom" anchor-offset="normal" popover="auto" data-view-component="true"> <div data-view-component="true" class="Overlay Overlay--size-auto"> <div data-view-component="true" class="Overlay-body Overlay-body--paddingNone"> <action-list> <div data-view-component="true"> <ul aria-labelledby="action-menu-71ffe330-c9a5-43eb-86da-ac681a060a20-button" id="action-menu-71ffe330-c9a5-43eb-86da-ac681a060a20-list" role="menu" data-view-component="true" class="ActionListWrap--inset ActionListWrap"> <li hidden="hidden" data-menu-item="i0code-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem"> <a tabindex="-1" id="item-1c01b3af-b50a-49ea-91a3-7e72b8447220" href="/ampproject/amphtml" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16"> <span class="ActionListItem-visual ActionListItem-visual--leading"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-code"> <path d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path> </svg> </span> <span data-view-component="true" class="ActionListItem-label"> Code </span> </a> </li> <li hidden="hidden" data-menu-item="i1issues-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem"> <a tabindex="-1" id="item-9d3c18e2-acae-41c7-ac43-8ab2defce948" href="/ampproject/amphtml/issues" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16"> <span class="ActionListItem-visual ActionListItem-visual--leading"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-issue-opened"> <path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path> </svg> </span> <span data-view-component="true" class="ActionListItem-label"> Issues </span> </a> </li> <li hidden="hidden" data-menu-item="i2pull-requests-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem"> <a tabindex="-1" id="item-dc46cb8a-0263-4acd-95e5-daee3da69a66" href="/ampproject/amphtml/pulls" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16"> <span class="ActionListItem-visual ActionListItem-visual--leading"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-git-pull-request"> <path d="M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25Zm5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354ZM3.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm0 9.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm8.25.75a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Z"></path> </svg> </span> <span data-view-component="true" class="ActionListItem-label"> Pull requests </span> </a> </li> <li hidden="hidden" data-menu-item="i3actions-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem"> <a tabindex="-1" id="item-75d4e52d-b55d-49d1-8c24-a95a2aca2c47" href="/ampproject/amphtml/actions" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16"> <span class="ActionListItem-visual ActionListItem-visual--leading"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-play"> <path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm4.879-2.773 4.264 2.559a.25.25 0 0 1 0 .428l-4.264 2.559A.25.25 0 0 1 6 10.559V5.442a.25.25 0 0 1 .379-.215Z"></path> </svg> </span> <span data-view-component="true" class="ActionListItem-label"> Actions </span> </a> </li> <li hidden="hidden" data-menu-item="i4projects-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem"> <a tabindex="-1" id="item-fd3e6e66-57f0-40c2-ba48-7b853d0b6d0f" href="/ampproject/amphtml/projects" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16"> <span class="ActionListItem-visual ActionListItem-visual--leading"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-table"> <path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25ZM6.5 6.5v8h7.75a.25.25 0 0 0 .25-.25V6.5Zm8-1.5V1.75a.25.25 0 0 0-.25-.25H6.5V5Zm-13 1.5v7.75c0 .138.112.25.25.25H5v-8ZM5 5V1.5H1.75a.25.25 0 0 0-.25.25V5Z"></path> </svg> </span> <span data-view-component="true" class="ActionListItem-label"> Projects </span> </a> </li> <li hidden="hidden" data-menu-item="i5security-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem"> <a tabindex="-1" id="item-e762340b-d455-4081-9fd1-aeda42363978" href="/ampproject/amphtml/security" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16"> <span class="ActionListItem-visual ActionListItem-visual--leading"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-shield"> <path d="M7.467.133a1.748 1.748 0 0 1 1.066 0l5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667Zm.61 1.429a.25.25 0 0 0-.153 0l-5.25 1.68a.25.25 0 0 0-.174.238V7c0 1.358.275 2.666 1.057 3.86.784 1.194 2.121 2.34 4.366 3.297a.196.196 0 0 0 .154 0c2.245-.956 3.582-2.104 4.366-3.298C13.225 9.666 13.5 8.36 13.5 7V3.48a.251.251 0 0 0-.174-.237l-5.25-1.68ZM8.75 4.75v3a.75.75 0 0 1-1.5 0v-3a.75.75 0 0 1 1.5 0ZM9 10.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path> </svg> </span> <span data-view-component="true" class="ActionListItem-label"> Security </span> </a> </li> <li hidden="hidden" data-menu-item="i6insights-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem"> <a tabindex="-1" id="item-bfa01537-f4c4-4f6d-9ede-9812eca14d9d" href="/ampproject/amphtml/pulse" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16"> <span class="ActionListItem-visual ActionListItem-visual--leading"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-graph"> <path d="M1.5 1.75V13.5h13.75a.75.75 0 0 1 0 1.5H.75a.75.75 0 0 1-.75-.75V1.75a.75.75 0 0 1 1.5 0Zm14.28 2.53-5.25 5.25a.75.75 0 0 1-1.06 0L7 7.06 4.28 9.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.25-3.25a.75.75 0 0 1 1.06 0L10 7.94l4.72-4.72a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path> </svg> </span> <span data-view-component="true" class="ActionListItem-label"> Insights </span> </a> </li> </ul> </div></action-list> </div> </div></anchored-position> </focus-group> </action-menu></div> </nav> </div> <turbo-frame id="repo-content-turbo-frame" target="_top" data-turbo-action="advance" class=""> <div id="repo-content-pjax-container" class="repository-content " > <react-app app-name="react-code-view" initial-path="/ampproject/amphtml/blob/main/extensions/amp-a4a/rtc-documentation.md" style="display: block; min-height: calc(100vh - 64px);" data-attempted-ssr="true" data-ssr="true" data-lazy="false" data-alternate="false" data-data-router-enabled="false" > <script type="application/json" data-target="react-app.embeddedData">{"payload":{"allShortcutsEnabled":false,"fileTree":{"extensions/amp-a4a":{"items":[{"name":"0.1","path":"extensions/amp-a4a/0.1","contentType":"directory"},{"name":"OWNERS","path":"extensions/amp-a4a/OWNERS","contentType":"file"},{"name":"RTCDiagram.png","path":"extensions/amp-a4a/RTCDiagram.png","contentType":"file"},{"name":"RTCDiagram2.png","path":"extensions/amp-a4a/RTCDiagram2.png","contentType":"file"},{"name":"amp-a4a-format.md","path":"extensions/amp-a4a/amp-a4a-format.md","contentType":"file"},{"name":"refresh.md","path":"extensions/amp-a4a/refresh.md","contentType":"file"},{"name":"rtc-documentation.md","path":"extensions/amp-a4a/rtc-documentation.md","contentType":"file"},{"name":"rtc-publisher-implementation-guide.md","path":"extensions/amp-a4a/rtc-publisher-implementation-guide.md","contentType":"file"}],"totalCount":8},"extensions":{"items":[{"name":"amp-3d-gltf","path":"extensions/amp-3d-gltf","contentType":"directory"},{"name":"amp-3q-player","path":"extensions/amp-3q-player","contentType":"directory"},{"name":"amp-a4a","path":"extensions/amp-a4a","contentType":"directory"},{"name":"amp-access-fewcents","path":"extensions/amp-access-fewcents","contentType":"directory"},{"name":"amp-access-laterpay","path":"extensions/amp-access-laterpay","contentType":"directory"},{"name":"amp-access-poool","path":"extensions/amp-access-poool","contentType":"directory"},{"name":"amp-access-scroll","path":"extensions/amp-access-scroll","contentType":"directory"},{"name":"amp-access","path":"extensions/amp-access","contentType":"directory"},{"name":"amp-accordion","path":"extensions/amp-accordion","contentType":"directory"},{"name":"amp-action-macro","path":"extensions/amp-action-macro","contentType":"directory"},{"name":"amp-ad-custom","path":"extensions/amp-ad-custom","contentType":"directory"},{"name":"amp-ad-exit","path":"extensions/amp-ad-exit","contentType":"directory"},{"name":"amp-ad-network-adsense-impl","path":"extensions/amp-ad-network-adsense-impl","contentType":"directory"},{"name":"amp-ad-network-adzerk-impl","path":"extensions/amp-ad-network-adzerk-impl","contentType":"directory"},{"name":"amp-ad-network-dianomi-impl","path":"extensions/amp-ad-network-dianomi-impl","contentType":"directory"},{"name":"amp-ad-network-doubleclick-impl","path":"extensions/amp-ad-network-doubleclick-impl","contentType":"directory"},{"name":"amp-ad-network-fake-impl","path":"extensions/amp-ad-network-fake-impl","contentType":"directory"},{"name":"amp-ad-network-mgid-impl","path":"extensions/amp-ad-network-mgid-impl","contentType":"directory"},{"name":"amp-ad-network-nws-impl","path":"extensions/amp-ad-network-nws-impl","contentType":"directory"},{"name":"amp-ad-network-oblivki-impl","path":"extensions/amp-ad-network-oblivki-impl","contentType":"directory"},{"name":"amp-ad-network-smartads-impl","path":"extensions/amp-ad-network-smartads-impl","contentType":"directory"},{"name":"amp-ad-network-smartadserver-impl","path":"extensions/amp-ad-network-smartadserver-impl","contentType":"directory"},{"name":"amp-ad-network-triplelift-impl","path":"extensions/amp-ad-network-triplelift-impl","contentType":"directory"},{"name":"amp-ad-network-valueimpression-impl","path":"extensions/amp-ad-network-valueimpression-impl","contentType":"directory"},{"name":"amp-ad","path":"extensions/amp-ad","contentType":"directory"},{"name":"amp-addthis","path":"extensions/amp-addthis","contentType":"directory"},{"name":"amp-analytics","path":"extensions/amp-analytics","contentType":"directory"},{"name":"amp-anim","path":"extensions/amp-anim","contentType":"directory"},{"name":"amp-animation-polyfill","path":"extensions/amp-animation-polyfill","contentType":"directory"},{"name":"amp-animation","path":"extensions/amp-animation","contentType":"directory"},{"name":"amp-apester-media","path":"extensions/amp-apester-media","contentType":"directory"},{"name":"amp-app-banner","path":"extensions/amp-app-banner","contentType":"directory"},{"name":"amp-audio","path":"extensions/amp-audio","contentType":"directory"},{"name":"amp-auto-ads","path":"extensions/amp-auto-ads","contentType":"directory"},{"name":"amp-auto-lightbox","path":"extensions/amp-auto-lightbox","contentType":"directory"},{"name":"amp-autocomplete","path":"extensions/amp-autocomplete","contentType":"directory"},{"name":"amp-base-carousel","path":"extensions/amp-base-carousel","contentType":"directory"},{"name":"amp-beopinion","path":"extensions/amp-beopinion","contentType":"directory"},{"name":"amp-bind","path":"extensions/amp-bind","contentType":"directory"},{"name":"amp-bodymovin-animation","path":"extensions/amp-bodymovin-animation","contentType":"directory"},{"name":"amp-brid-player","path":"extensions/amp-brid-player","contentType":"directory"},{"name":"amp-brightcove","path":"extensions/amp-brightcove","contentType":"directory"},{"name":"amp-byside-content","path":"extensions/amp-byside-content","contentType":"directory"},{"name":"amp-cache-url","path":"extensions/amp-cache-url","contentType":"directory"},{"name":"amp-call-tracking","path":"extensions/amp-call-tracking","contentType":"directory"},{"name":"amp-carousel","path":"extensions/amp-carousel","contentType":"directory"},{"name":"amp-connatix-player","path":"extensions/amp-connatix-player","contentType":"directory"},{"name":"amp-consent","path":"extensions/amp-consent","contentType":"directory"},{"name":"amp-crypto-polyfill","path":"extensions/amp-crypto-polyfill","contentType":"directory"},{"name":"amp-dailymotion","path":"extensions/amp-dailymotion","contentType":"directory"},{"name":"amp-date-countdown","path":"extensions/amp-date-countdown","contentType":"directory"},{"name":"amp-date-display","path":"extensions/amp-date-display","contentType":"directory"},{"name":"amp-date-picker","path":"extensions/amp-date-picker","contentType":"directory"},{"name":"amp-delight-player","path":"extensions/amp-delight-player","contentType":"directory"},{"name":"amp-dynamic-css-classes","path":"extensions/amp-dynamic-css-classes","contentType":"directory"},{"name":"amp-embedly-card","path":"extensions/amp-embedly-card","contentType":"directory"},{"name":"amp-experiment","path":"extensions/amp-experiment","contentType":"directory"},{"name":"amp-facebook-comments","path":"extensions/amp-facebook-comments","contentType":"directory"},{"name":"amp-facebook-like","path":"extensions/amp-facebook-like","contentType":"directory"},{"name":"amp-facebook-page","path":"extensions/amp-facebook-page","contentType":"directory"},{"name":"amp-facebook","path":"extensions/amp-facebook","contentType":"directory"},{"name":"amp-fit-text","path":"extensions/amp-fit-text","contentType":"directory"},{"name":"amp-font","path":"extensions/amp-font","contentType":"directory"},{"name":"amp-form","path":"extensions/amp-form","contentType":"directory"},{"name":"amp-fx-collection","path":"extensions/amp-fx-collection","contentType":"directory"},{"name":"amp-fx-flying-carpet","path":"extensions/amp-fx-flying-carpet","contentType":"directory"},{"name":"amp-geo","path":"extensions/amp-geo","contentType":"directory"},{"name":"amp-gfycat","path":"extensions/amp-gfycat","contentType":"directory"},{"name":"amp-gist","path":"extensions/amp-gist","contentType":"directory"},{"name":"amp-google-document-embed","path":"extensions/amp-google-document-embed","contentType":"directory"},{"name":"amp-google-read-aloud-player","path":"extensions/amp-google-read-aloud-player","contentType":"directory"},{"name":"amp-gwd-animation","path":"extensions/amp-gwd-animation","contentType":"directory"},{"name":"amp-hulu","path":"extensions/amp-hulu","contentType":"directory"},{"name":"amp-iframe","path":"extensions/amp-iframe","contentType":"directory"},{"name":"amp-iframely","path":"extensions/amp-iframely","contentType":"directory"},{"name":"amp-ima-video","path":"extensions/amp-ima-video","contentType":"directory"},{"name":"amp-image-lightbox","path":"extensions/amp-image-lightbox","contentType":"directory"},{"name":"amp-image-slider","path":"extensions/amp-image-slider","contentType":"directory"},{"name":"amp-image-viewer","path":"extensions/amp-image-viewer","contentType":"directory"},{"name":"amp-imgur","path":"extensions/amp-imgur","contentType":"directory"},{"name":"amp-inline-gallery","path":"extensions/amp-inline-gallery","contentType":"directory"},{"name":"amp-inputmask","path":"extensions/amp-inputmask","contentType":"directory"},{"name":"amp-instagram","path":"extensions/amp-instagram","contentType":"directory"},{"name":"amp-install-serviceworker","path":"extensions/amp-install-serviceworker","contentType":"directory"},{"name":"amp-intersection-observer-polyfill","path":"extensions/amp-intersection-observer-polyfill","contentType":"directory"},{"name":"amp-izlesene","path":"extensions/amp-izlesene","contentType":"directory"},{"name":"amp-jwplayer","path":"extensions/amp-jwplayer","contentType":"directory"},{"name":"amp-kaltura-player","path":"extensions/amp-kaltura-player","contentType":"directory"},{"name":"amp-lightbox-gallery","path":"extensions/amp-lightbox-gallery","contentType":"directory"},{"name":"amp-lightbox","path":"extensions/amp-lightbox","contentType":"directory"},{"name":"amp-link-rewriter","path":"extensions/amp-link-rewriter","contentType":"directory"},{"name":"amp-list","path":"extensions/amp-list","contentType":"directory"},{"name":"amp-live-list","path":"extensions/amp-live-list","contentType":"directory"},{"name":"amp-loader","path":"extensions/amp-loader","contentType":"directory"},{"name":"amp-mathml","path":"extensions/amp-mathml","contentType":"directory"},{"name":"amp-mega-menu","path":"extensions/amp-mega-menu","contentType":"directory"},{"name":"amp-megaphone","path":"extensions/amp-megaphone","contentType":"directory"},{"name":"amp-minute-media-player","path":"extensions/amp-minute-media-player","contentType":"directory"},{"name":"amp-mowplayer","path":"extensions/amp-mowplayer","contentType":"directory"},{"name":"amp-mraid","path":"extensions/amp-mraid","contentType":"directory"},{"name":"amp-mustache","path":"extensions/amp-mustache","contentType":"directory"},{"name":"amp-nested-menu","path":"extensions/amp-nested-menu","contentType":"directory"},{"name":"amp-next-page","path":"extensions/amp-next-page","contentType":"directory"},{"name":"amp-nexxtv-player","path":"extensions/amp-nexxtv-player","contentType":"directory"},{"name":"amp-o2-player","path":"extensions/amp-o2-player","contentType":"directory"},{"name":"amp-onetap-google","path":"extensions/amp-onetap-google","contentType":"directory"},{"name":"amp-ooyala-player","path":"extensions/amp-ooyala-player","contentType":"directory"},{"name":"amp-orientation-observer","path":"extensions/amp-orientation-observer","contentType":"directory"},{"name":"amp-pan-zoom","path":"extensions/amp-pan-zoom","contentType":"directory"},{"name":"amp-pinterest","path":"extensions/amp-pinterest","contentType":"directory"},{"name":"amp-playbuzz","path":"extensions/amp-playbuzz","contentType":"directory"},{"name":"amp-position-observer","path":"extensions/amp-position-observer","contentType":"directory"},{"name":"amp-powr-player","path":"extensions/amp-powr-player","contentType":"directory"},{"name":"amp-reach-player","path":"extensions/amp-reach-player","contentType":"directory"},{"name":"amp-recaptcha-input","path":"extensions/amp-recaptcha-input","contentType":"directory"},{"name":"amp-redbull-player","path":"extensions/amp-redbull-player","contentType":"directory"},{"name":"amp-reddit","path":"extensions/amp-reddit","contentType":"directory"},{"name":"amp-render","path":"extensions/amp-render","contentType":"directory"},{"name":"amp-resize-observer-polyfill","path":"extensions/amp-resize-observer-polyfill","contentType":"directory"},{"name":"amp-riddle-quiz","path":"extensions/amp-riddle-quiz","contentType":"directory"},{"name":"amp-script","path":"extensions/amp-script","contentType":"directory"},{"name":"amp-selector","path":"extensions/amp-selector","contentType":"directory"},{"name":"amp-shadow-dom-polyfill","path":"extensions/amp-shadow-dom-polyfill","contentType":"directory"},{"name":"amp-sidebar","path":"extensions/amp-sidebar","contentType":"directory"},{"name":"amp-skimlinks","path":"extensions/amp-skimlinks","contentType":"directory"},{"name":"amp-slides","path":"extensions/amp-slides","contentType":"directory"},{"name":"amp-slikeplayer","path":"extensions/amp-slikeplayer","contentType":"directory"},{"name":"amp-smartlinks","path":"extensions/amp-smartlinks","contentType":"directory"},{"name":"amp-social-share","path":"extensions/amp-social-share","contentType":"directory"},{"name":"amp-soundcloud","path":"extensions/amp-soundcloud","contentType":"directory"},{"name":"amp-springboard-player","path":"extensions/amp-springboard-player","contentType":"directory"},{"name":"amp-standalone","path":"extensions/amp-standalone","contentType":"directory"},{"name":"amp-sticky-ad","path":"extensions/amp-sticky-ad","contentType":"directory"},{"name":"amp-story-360","path":"extensions/amp-story-360","contentType":"directory"},{"name":"amp-story-audio-sticker","path":"extensions/amp-story-audio-sticker","contentType":"directory"},{"name":"amp-story-auto-ads","path":"extensions/amp-story-auto-ads","contentType":"directory"},{"name":"amp-story-auto-analytics","path":"extensions/amp-story-auto-analytics","contentType":"directory"},{"name":"amp-story-captions","path":"extensions/amp-story-captions","contentType":"directory"},{"name":"amp-story-dev-tools","path":"extensions/amp-story-dev-tools","contentType":"directory"},{"name":"amp-story-education","path":"extensions/amp-story-education","contentType":"directory"},{"name":"amp-story-interactive","path":"extensions/amp-story-interactive","contentType":"directory"},{"name":"amp-story-page-attachment","path":"extensions/amp-story-page-attachment","contentType":"directory"},{"name":"amp-story-panning-media","path":"extensions/amp-story-panning-media","contentType":"directory"},{"name":"amp-story-player","path":"extensions/amp-story-player","contentType":"directory"},{"name":"amp-story-share-menu","path":"extensions/amp-story-share-menu","contentType":"directory"},{"name":"amp-story-shopping","path":"extensions/amp-story-shopping","contentType":"directory"},{"name":"amp-story-subscriptions","path":"extensions/amp-story-subscriptions","contentType":"directory"},{"name":"amp-story","path":"extensions/amp-story","contentType":"directory"},{"name":"amp-stream-gallery","path":"extensions/amp-stream-gallery","contentType":"directory"},{"name":"amp-subscriptions-google","path":"extensions/amp-subscriptions-google","contentType":"directory"},{"name":"amp-subscriptions","path":"extensions/amp-subscriptions","contentType":"directory"},{"name":"amp-tiktok","path":"extensions/amp-tiktok","contentType":"directory"},{"name":"amp-timeago","path":"extensions/amp-timeago","contentType":"directory"},{"name":"amp-truncate-text","path":"extensions/amp-truncate-text","contentType":"directory"},{"name":"amp-twitter","path":"extensions/amp-twitter","contentType":"directory"},{"name":"amp-user-notification","path":"extensions/amp-user-notification","contentType":"directory"},{"name":"amp-video-docking","path":"extensions/amp-video-docking","contentType":"directory"},{"name":"amp-video-iframe","path":"extensions/amp-video-iframe","contentType":"directory"},{"name":"amp-video","path":"extensions/amp-video","contentType":"directory"},{"name":"amp-viewer-integration","path":"extensions/amp-viewer-integration","contentType":"directory"},{"name":"amp-vimeo","path":"extensions/amp-vimeo","contentType":"directory"},{"name":"amp-vine","path":"extensions/amp-vine","contentType":"directory"},{"name":"amp-viqeo-player","path":"extensions/amp-viqeo-player","contentType":"directory"},{"name":"amp-vk","path":"extensions/amp-vk","contentType":"directory"},{"name":"amp-web-push","path":"extensions/amp-web-push","contentType":"directory"},{"name":"amp-wistia-player","path":"extensions/amp-wistia-player","contentType":"directory"},{"name":"amp-wordpress-embed","path":"extensions/amp-wordpress-embed","contentType":"directory"},{"name":"amp-yotpo","path":"extensions/amp-yotpo","contentType":"directory"},{"name":"amp-youtube","path":"extensions/amp-youtube","contentType":"directory"},{"name":"BUILD","path":"extensions/BUILD","contentType":"file"},{"name":"OWNERS","path":"extensions/OWNERS","contentType":"file"},{"name":"README.md","path":"extensions/README.md","contentType":"file"},{"name":"WORKSPACE","path":"extensions/WORKSPACE","contentType":"file"}],"totalCount":173},"":{"items":[{"name":".circleci","path":".circleci","contentType":"directory"},{"name":".github","path":".github","contentType":"directory"},{"name":".vscode","path":".vscode","contentType":"directory"},{"name":"3p","path":"3p","contentType":"directory"},{"name":"ads","path":"ads","contentType":"directory"},{"name":"build-system","path":"build-system","contentType":"directory"},{"name":"css","path":"css","contentType":"directory"},{"name":"docs","path":"docs","contentType":"directory"},{"name":"examples","path":"examples","contentType":"directory"},{"name":"extensions","path":"extensions","contentType":"directory"},{"name":"src","path":"src","contentType":"directory"},{"name":"test","path":"test","contentType":"directory"},{"name":"testing","path":"testing","contentType":"directory"},{"name":"third_party","path":"third_party","contentType":"directory"},{"name":"tools","path":"tools","contentType":"directory"},{"name":"validator","path":"validator","contentType":"directory"},{"name":".editorconfig","path":".editorconfig","contentType":"file"},{"name":".eslint-plugin-local.js","path":".eslint-plugin-local.js","contentType":"file"},{"name":".eslintignore","path":".eslintignore","contentType":"file"},{"name":".eslintrc.js","path":".eslintrc.js","contentType":"file"},{"name":".gitattributes","path":".gitattributes","contentType":"file"},{"name":".gitignore","path":".gitignore","contentType":"file"},{"name":".lando.yml","path":".lando.yml","contentType":"file"},{"name":".lgtm.yml","path":".lgtm.yml","contentType":"file"},{"name":".npmrc","path":".npmrc","contentType":"file"},{"name":".prettierignore","path":".prettierignore","contentType":"file"},{"name":".prettierrc","path":".prettierrc","contentType":"file"},{"name":".renovaterc.json","path":".renovaterc.json","contentType":"file"},{"name":"CODE_OF_CONDUCT.md","path":"CODE_OF_CONDUCT.md","contentType":"file"},{"name":"LICENSE","path":"LICENSE","contentType":"file"},{"name":"OWNERS","path":"OWNERS","contentType":"file"},{"name":"README.md","path":"README.md","contentType":"file"},{"name":"SECURITY.md","path":"SECURITY.md","contentType":"file"},{"name":"amp.js","path":"amp.js","contentType":"file"},{"name":"babel.config.js","path":"babel.config.js","contentType":"file"},{"name":"codecov.yml","path":"codecov.yml","contentType":"file"},{"name":"package-lock.json","path":"package-lock.json","contentType":"file"},{"name":"package-scripts.js","path":"package-scripts.js","contentType":"file"},{"name":"package.json","path":"package.json","contentType":"file"},{"name":"tsconfig.base.json","path":"tsconfig.base.json","contentType":"file"},{"name":"tsconfig.json","path":"tsconfig.json","contentType":"file"}],"totalCount":41}},"fileTreeProcessingTime":79.801563,"foldersToFetch":[],"repo":{"id":41766002,"defaultBranch":"main","name":"amphtml","ownerLogin":"ampproject","currentUserCanPush":false,"isFork":false,"isEmpty":false,"createdAt":"2015-09-01T22:10:53.000Z","ownerAvatar":"https://avatars.githubusercontent.com/u/14114390?v=4","public":true,"private":false,"isOrgOwned":true},"codeLineWrapEnabled":false,"symbolsExpanded":false,"treeExpanded":true,"refInfo":{"name":"main","listCacheKey":"v0:1740470547.0","canEdit":false,"refType":"branch","currentOid":"e742aa10f22d5366ae37bf7f17a73c7332ecf179"},"path":"extensions/amp-a4a/rtc-documentation.md","currentUser":null,"blob":{"rawLines":null,"stylingDirectives":null,"colorizedLines":null,"csv":null,"csvError":null,"dependabotInfo":{"showConfigurationBanner":false,"configFilePath":null,"networkDependabotPath":"/ampproject/amphtml/network/updates","dismissConfigurationNoticePath":"/settings/dismiss-notice/dependabot_configuration_notice","configurationNoticeDismissed":null},"displayName":"rtc-documentation.md","displayUrl":"https://github.com/ampproject/amphtml/blob/main/extensions/amp-a4a/rtc-documentation.md?raw=true","headerInfo":{"blobSize":"37.8 KB","deleteTooltip":"You must be signed in to make or propose changes","editTooltip":"You must be signed in to make or propose changes","ghDesktopPath":"https://desktop.github.com","isGitLfs":false,"onBranch":true,"shortPath":"a2d5ef7","siteNavLoginPath":"/login?return_to=https%3A%2F%2Fgithub.com%2Fampproject%2Famphtml%2Fblob%2Fmain%2Fextensions%2Famp-a4a%2Frtc-documentation.md","isCSV":false,"isRichtext":true,"toc":[{"level":1,"text":"AMP Real Time Config","anchor":"amp-real-time-config","htmlText":"AMP Real Time Config"},{"level":2,"text":"Objective","anchor":"objective","htmlText":"Objective"},{"level":2,"text":"Background","anchor":"background","htmlText":"Background"},{"level":2,"text":"Overview","anchor":"overview","htmlText":"Overview"},{"level":3,"text":"Custom URL callout","anchor":"custom-url-callout","htmlText":"Custom URL callout"},{"level":3,"text":"Vendor-specified URL Callout","anchor":"vendor-specified-url-callout","htmlText":"Vendor-specified URL Callout"},{"level":2,"text":"Design","anchor":"design","htmlText":"Design"},{"level":3,"text":"Per-Slot RTC Specification","anchor":"per-slot-rtc-specification","htmlText":"Per-Slot RTC Specification"},{"level":4,"text":"Example 1: RTC specification on an amp-ad","anchor":"example-1-rtc-specification-on-an-amp-ad","htmlText":"Example 1: RTC specification on an amp-ad"},{"level":3,"text":"Vendor URL Specification","anchor":"vendor-url-specification","htmlText":"Vendor URL Specification"},{"level":4,"text":"Currently Supported Vendors","anchor":"currently-supported-vendors","htmlText":"Currently Supported Vendors"},{"level":3,"text":"RTC Callout Request Specification","anchor":"rtc-callout-request-specification","htmlText":"RTC Callout Request Specification"},{"level":3,"text":"RTC Callout Endpoint and Response Specification","anchor":"rtc-callout-endpoint-and-response-specification","htmlText":"RTC Callout Endpoint and Response Specification"},{"level":3,"text":"RTC Error Pingback","anchor":"rtc-error-pingback","htmlText":"RTC Error Pingback"},{"level":3,"text":"AMP Consent Integration","anchor":"amp-consent-integration","htmlText":"AMP Consent Integration"},{"level":4,"text":"Allow all RTC callouts for all consent states","anchor":"allow-all-rtc-callouts-for-all-consent-states","htmlText":"Allow all RTC callouts for all consent states"},{"level":4,"text":"Allow all RTC callouts for only certain consent states","anchor":"allow-all-rtc-callouts-for-only-certain-consent-states","htmlText":"Allow all RTC callouts for only certain consent states"},{"level":4,"text":"Allow some RTC callouts in the \"url\" array","anchor":"allow-some-rtc-callouts-in-the-url-array","htmlText":"Allow some RTC callouts in the \"url\" array"},{"level":4,"text":"Allow some RTC callouts in the \"vendors\" object","anchor":"allow-some-rtc-callouts-in-the-vendors-object","htmlText":"Allow some RTC callouts in the \"vendors\" object"},{"level":4,"text":"Mixture of settings","anchor":"mixture-of-settings","htmlText":"Mixture of settings"},{"level":3,"text":"Blocking RTC","anchor":"blocking-rtc","htmlText":"Blocking RTC"},{"level":3,"text":"URL Macro Substitution","anchor":"url-macro-substitution","htmlText":"URL Macro Substitution"},{"level":4,"text":"Vendor Defined Macros","anchor":"vendor-defined-macros","htmlText":"Vendor Defined Macros"},{"level":5,"text":"Example 2: Use of Vendor URLs","anchor":"example-2-use-of-vendor-urls","htmlText":"Example 2: Use of Vendor URLs"},{"level":4,"text":"Fast Fetch Implementation Defined Macros","anchor":"fast-fetch-implementation-defined-macros","htmlText":"Fast Fetch Implementation Defined Macros"},{"level":5,"text":"Example 3: Fast Fetch implementation defined macros","anchor":"example-3-fast-fetch-implementation-defined-macros","htmlText":"Example 3: Fast Fetch implementation defined macros"},{"level":5,"text":"Vendor Macro Substitution with Fast Fetch Network Macro Substitution","anchor":"vendor-macro-substitution-with-fast-fetch-network-macro-substitution","htmlText":"Vendor Macro Substitution with Fast Fetch Network Macro Substitution"},{"level":6,"text":"Example 4","anchor":"example-4","htmlText":"Example 4"},{"level":5,"text":"Conflicting macro substitution","anchor":"conflicting-macro-substitution","htmlText":"Conflicting macro substitution"},{"level":3,"text":"RTC Callout Result Merging","anchor":"rtc-callout-result-merging","htmlText":"RTC Callout Result Merging"},{"level":3,"text":"Error Cases","anchor":"error-cases","htmlText":"Error Cases"},{"level":5,"text":"Misconfigured RTC Config","anchor":"misconfigured-rtc-config","htmlText":"Misconfigured RTC Config"},{"level":5,"text":"Bad JSON Response","anchor":"bad-json-response","htmlText":"Bad JSON Response"},{"level":5,"text":"Duplicate Callout URLs","anchor":"duplicate-callout-urls","htmlText":"Duplicate Callout URLs"},{"level":5,"text":"Insecure URLs","anchor":"insecure-urls","htmlText":"Insecure URLs"},{"level":5,"text":"Maximum Callouts Exceeded","anchor":"maximum-callouts-exceeded","htmlText":"Maximum Callouts Exceeded"},{"level":5,"text":"Network Failure","anchor":"network-failure","htmlText":"Network Failure"},{"level":5,"text":"Unknown Vendor","anchor":"unknown-vendor","htmlText":"Unknown Vendor"},{"level":5,"text":"Timeout","anchor":"timeout","htmlText":"Timeout"},{"level":3,"text":"Single Request Architecture (SRA) Support","anchor":"single-request-architecture-sra-support","htmlText":"Single Request Architecture (SRA) Support"},{"level":2,"text":"End-to-End Example","anchor":"end-to-end-example","htmlText":"End-to-End Example"}],"lineInfo":{"truncatedLoc":"861","truncatedSloc":"673"},"mode":"file"},"image":false,"isCodeownersFile":null,"isPlain":false,"isValidLegacyIssueTemplate":false,"issueTemplate":null,"discussionTemplate":null,"language":"Markdown","languageID":222,"large":false,"planSupportInfo":{"repoIsFork":null,"repoOwnedByCurrentUser":null,"requestFullPath":"/ampproject/amphtml/blob/main/extensions/amp-a4a/rtc-documentation.md","showFreeOrgGatedFeatureMessage":null,"showPlanSupportBanner":null,"upgradeDataAttributes":null,"upgradePath":null},"publishBannersInfo":{"dismissActionNoticePath":"/settings/dismiss-notice/publish_action_from_dockerfile","releasePath":"/ampproject/amphtml/releases/new?marketplace=true","showPublishActionBanner":false},"rawBlobUrl":"https://github.com/ampproject/amphtml/raw/refs/heads/main/extensions/amp-a4a/rtc-documentation.md","renderImageOrRaw":false,"richText":"\u003carticle class=\"markdown-body entry-content container-lg\" itemprop=\"text\"\u003e\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch1 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eAMP Real Time Config\u003c/h1\u003e\u003ca id=\"user-content-amp-real-time-config\" class=\"anchor\" aria-label=\"Permalink: AMP Real Time Config\" href=\"#amp-real-time-config\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eObjective\u003c/h2\u003e\u003ca id=\"user-content-objective\" class=\"anchor\" aria-label=\"Permalink: Objective\" href=\"#objective\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eFor AMP Fast Fetch, support publisher-specified, multiple, simultaneous callouts in order to augment targeting information included in the ad request.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eBackground\u003c/h2\u003e\u003ca id=\"user-content-background\" class=\"anchor\" aria-label=\"Permalink: Background\" href=\"#background\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eRemote HTML support was added for Delayed Fetch to support first-party cookie targeting. This was because AMP does not allow custom JavaScript, and pages served from the AMP cache are identical for each user. However, Remote HTML leverages the fact that custom JavaScript execution occurs as a part of generating an ad request via Delayed Fetch. Fast Fetch allows for sending the ad request early by moving all code related to ad generation within the AMP runtime, disallowing any custom JavaScript as part of ad request creation. Therefore Fast Fetch is incompatible with Remote HTML. Real Time Config (RTC) has been added as an optional feature of Fast Fetch to allow for publishers to add user-targeting information to ad requests from AMP pages in a generic way that can be utilized by any ad networks, and any user-targeting vendors. Common use cases for RTC are to retrieve 1st party or 3rd party data, or to integrate 3rd party demand, also known as Header Bidding.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eOverview\u003c/h2\u003e\u003ca id=\"user-content-overview\" class=\"anchor\" aria-label=\"Permalink: Overview\" href=\"#overview\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe design of RTC is per-slot, with a \u003cstrong\u003emaximum of 5 parallel callouts allowed per slot\u003c/strong\u003e. RTC is usable by any Fast Fetch network implementation. Call-outs for all slots will be sent as soon as possible. There are two different types of callouts that will be supported:\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eCustom URL callout\u003c/h3\u003e\u003ca id=\"user-content-custom-url-callout\" class=\"anchor\" aria-label=\"Permalink: Custom URL callout\" href=\"#custom-url-callout\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe publisher specifies a custom URL that should be called out to. For example, a publisher may specify their own targeting server as a custom URL. If the ad network in use supports macro substitution for custom URLs, the publisher may specify macros in the URL. See the \u003ca href=\"#url-macro-substitution\"\u003eURL Macro Substitution\u003c/a\u003e section for details.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eVendor-specified URL Callout\u003c/h3\u003e\u003ca id=\"user-content-vendor-specified-url-callout\" class=\"anchor\" aria-label=\"Permalink: Vendor-specified URL Callout\" href=\"#vendor-specified-url-callout\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eRTC supports call-outs to third-party vendors. For example, take VendorFooBar which provides an API service that returns similar interests when provided a given interest (i.e. \"baseball\" yields [\"sports\", \"apple-pie\"]). If VendorFooBar wants publishers to be able to use them for RTC call outs, they simply add their call-out url with built-in macros to the AMP RTC vendor registry. Then publishers specify that they want to call out to VendorFooBar, and supply the value to substitute into the macro. This gives the Vendor complete control over the actual URL, with the Publisher only needing to supply the relevant inputs. See the \u003ca href=\"#url-macro-substitution\"\u003eURL Macro Substitution\u003c/a\u003e section for details.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIn both cases, the results of these call-outs are passed to the Fast Fetch implementations as part of ad url construction via the \u003cstrong\u003e\u003ccode\u003egetAdUrl\u003c/code\u003e\u003c/strong\u003e method. The ad network Fast Fetch implementation then uses results of these callouts to generate the ad URL. The semantics of how the ad network uses the RTC results to general the ad URL is specific to each individual network's implementation of Fast Fetch, so please refer to network-specific documentation for details.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eDesign\u003c/h2\u003e\u003ca id=\"user-content-design\" class=\"anchor\" aria-label=\"Permalink: Design\" href=\"#design\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003ePer-Slot RTC Specification\u003c/h3\u003e\u003ca id=\"user-content-per-slot-rtc-specification\" class=\"anchor\" aria-label=\"Permalink: Per-Slot RTC Specification\" href=\"#per-slot-rtc-specification\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003ePublishers may use RTC to send callouts to a maximum of 5 different endpoints. Each \u003ccode\u003eamp-ad\u003c/code\u003e element that uses RTC must have the \u003ccode\u003ertc-config\u003c/code\u003e attribute set with valid JSON.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eExample 1: RTC specification on an amp-ad\u003c/h4\u003e\u003ca id=\"user-content-example-1-rtc-specification-on-an-amp-ad\" class=\"anchor\" aria-label=\"Permalink: Example 1: RTC specification on an amp-ad\" href=\"#example-1-rtc-specification-on-an-amp-ad\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-text-html-basic notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"\u0026lt;amp-ad\n width=\u0026quot;320\u0026quot;\n height=\u0026quot;50\u0026quot;\n type=\u0026quot;network-foo\u0026quot;\n data-slot=\u0026quot;/1234/5678\u0026quot;\n rtc-config='{\n \u0026quot;vendors\u0026quot;: {\n \u0026quot;vendorA\u0026quot;: {\u0026quot;SLOT_ID\u0026quot;: \u0026quot;1\u0026quot;},\n \u0026quot;vendorB\u0026quot;: {\u0026quot;PAGE_ID\u0026quot;: \u0026quot;2\u0026quot;},\n \u0026quot;vendorC\u0026quot;: {\u0026quot;SLOT_W\u0026quot;: \u0026quot;320\u0026quot;, \u0026quot;SLOT_H\u0026quot;: \u0026quot;50\u0026quot;}\n },\n \u0026quot;urls\u0026quot;: [\n \u0026quot;https://www.AmpPublisher.biz/targetingA\u0026quot;,\n \u0026quot;https://www.AmpPublisher.biz/targetingB\u0026quot;\n ],\n \u0026quot;timeoutMillis\u0026quot;: 750}'\n\u0026gt;\n\u0026lt;/amp-ad\u0026gt;\"\u003e\u003cpre\u003e\u003cspan class=\"pl-kos\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003eamp-ad\u003c/span\u003e\n \u003cspan class=\"pl-c1\"\u003ewidth\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e320\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003eheight\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e50\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003etype\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003enetwork-foo\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003edata-slot\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e/1234/5678\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003ertc-config\u003c/span\u003e='\u003cspan class=\"pl-s\"\u003e{\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendors\": {\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendorA\": {\"SLOT_ID\": \"1\"},\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendorB\": {\"PAGE_ID\": \"2\"},\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendorC\": {\"SLOT_W\": \"320\", \"SLOT_H\": \"50\"}\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e },\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"urls\": [\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"https://www.AmpPublisher.biz/targetingA\",\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"https://www.AmpPublisher.biz/targetingB\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e ],\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"timeoutMillis\": 750}\u003c/span\u003e'\n\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003eamp-ad\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe value of \u003ccode\u003ertc-config\u003c/code\u003e must conform to the following specification:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-json notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"{\n \u0026quot;vendors\u0026quot;: {\n \u0026quot;vendor1\u0026quot;: {\n \u0026quot;MACRO_1\u0026quot;: \u0026quot;MACRO_VALUE_1\u0026quot;,\n \u0026quot;MACRO_2\u0026quot;: \u0026quot;MACRO_VALUE_2\u0026quot;\n },\n \u0026quot;vendor2\u0026quot;: {\n \u0026quot;MACRO_1\u0026quot;: \u0026quot;MACRO_VALUE_1\u0026quot;,\n \u0026quot;MACRO_2\u0026quot;: \u0026quot;MACRO_VALUE_2\u0026quot;\n }\n },\n \u0026quot;urls\u0026quot;: [\n \u0026quot;https://www.exampleA.com/endpoint\u0026quot;,\n {\n \u0026quot;url\u0026quot;: \u0026quot;https://www.exampleB.com/endpoint\u0026quot;,\n \u0026quot;errorReportingUrl\u0026quot;: \u0026quot;https://www.exampleB.com/endpoint?e=ERROR_TYPE\u0026amp;h=HREF\u0026quot;\n }\n ],\n \u0026quot;timeoutMillis\u0026quot;: 500\n}\"\u003e\u003cpre\u003e{\n \u003cspan class=\"pl-ent\"\u003e\"vendors\"\u003c/span\u003e: {\n \u003cspan class=\"pl-ent\"\u003e\"vendor1\"\u003c/span\u003e: {\n \u003cspan class=\"pl-ent\"\u003e\"MACRO_1\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eMACRO_VALUE_1\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n \u003cspan class=\"pl-ent\"\u003e\"MACRO_2\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eMACRO_VALUE_2\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e\n },\n \u003cspan class=\"pl-ent\"\u003e\"vendor2\"\u003c/span\u003e: {\n \u003cspan class=\"pl-ent\"\u003e\"MACRO_1\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eMACRO_VALUE_1\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n \u003cspan class=\"pl-ent\"\u003e\"MACRO_2\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eMACRO_VALUE_2\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e\n }\n },\n \u003cspan class=\"pl-ent\"\u003e\"urls\"\u003c/span\u003e: [\n \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ehttps://www.exampleA.com/endpoint\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n {\n \u003cspan class=\"pl-ent\"\u003e\"url\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ehttps://www.exampleB.com/endpoint\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n \u003cspan class=\"pl-ent\"\u003e\"errorReportingUrl\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ehttps://www.exampleB.com/endpoint?e=ERROR_TYPE\u0026amp;h=HREF\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e\n }\n ],\n \u003cspan class=\"pl-ent\"\u003e\"timeoutMillis\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e500\u003c/span\u003e\n}\u003c/pre\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003evendors\u003c/code\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eOptional parameter\u003c/li\u003e\n\u003cli\u003eType: Object\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eKey is the name of the vendor to use.\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eVendor to use must appear as a key in \u003ca href=\"https://github.com/ampproject/amphtml/blob/main/src/service/real-time-config/callout-vendors.js\"\u003ecallout-vendors.js\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eValue is a mapping of macros to values.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eMacros for a given vendor URL are specified by that particular vendor.\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eFor example, in the Example 1 above, VendorA has specified the macro SLOT_ID in their callout URL (see \u003ca href=\"#vendor-url-specification\"\u003eVendor URL Specification\u003c/a\u003e). The RTC config specifies the value \"1\" to substitute for SLOT_ID in the callout URL. You may also set the value of a macro as a JSON object or array. This JSON object will be stringified automatically prior to replacement in the URL.\u003c/li\u003e\n\u003cli\u003eVendors can use the same macros as other vendors.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eurls\u003c/code\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eOptional parameter\u003c/li\u003e\n\u003cli\u003eType: Array of strings or objects.\u003c/li\u003e\n\u003cli\u003eEach value in the array must be a valid RTC endpoint URL, or an object that contains a \u003ccode\u003eurl\u003c/code\u003e and an \u003ccode\u003eerrorReportingUrl\u003c/code\u003e as URL strings. Note that all URL strings must be secure (i.e. start with HTTPS). The array can be a mix of both of these types, as seen in the example above. In the case that an object is specified, the \u003ccode\u003eurl\u003c/code\u003e within this object is treated equivalently as if it had been specified directly within the array, and errors from callouts to that URL are sent to its corresponding \u003cstrong\u003eerrorReportingUrl\u003c/strong\u003e. The URLs specified here are the \"custom URLs\" mentioned above and throughout this document.\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eSee \u003ca href=\"#rtc-callout-endpoint-and-response-specification\"\u003eRTC Callout Endpoint and Response Specification\u003c/a\u003e section below on all requirements for endpoint.\u003c/li\u003e\n\u003cli\u003eSee \u003ca href=\"#rtc-error-pingback\"\u003eRTC Error Pingback\u003c/a\u003e section below for information on how errorReportingUrl is used to send sampled RTC errors, and how to specify an errorReportingUrl.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003etimeoutMillis\u003c/code\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eOptional parameter\u003c/li\u003e\n\u003cli\u003eType: integer\u003c/li\u003e\n\u003cli\u003eValue in milliseconds for timeout to use for each individual RTC callout. Must be less than default value of 1000ms, and greater than 0.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eWhile all three parameters of rtc-config are optional, either \"vendors\" or \"urls\" \u003cem\u003emust be specified\u003c/em\u003e for RTC to occur. Both may be specified simultaneously. If neither \"vendors\" nor \"urls\" are specified, there are no endpoints to callout to and RTC is aborted. An error will be logged to the console.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eVendor URL Specification\u003c/h3\u003e\u003ca id=\"user-content-vendor-url-specification\" class=\"anchor\" aria-label=\"Permalink: Vendor URL Specification\" href=\"#vendor-url-specification\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eTo spare publishers the details of having to construct URLs for external vendors, vendors may register a URL with macros in a central file called \u003ca href=\"https://github.com/ampproject/amphtml/blob/main/src/service/real-time-config/callout-vendors.js\"\u003ecallout-vendors.js\u003c/a\u003e, which maps unique vendor names to an object which includes a URL and a list of allowed macros that can be substituted into \u003ccode\u003eurl\u003c/code\u003e. Vendors may include these macros in their URLs, which publishers can then specify the value for. Additionally, vendors may specify an \u003ccode\u003eerrorReportingUrl\u003c/code\u003e. This errorReportingUrl will be sent 1% sampled-per-page errors from callouts to their RTC endpoint. For instance:\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"/** amp-a4a/0.1/callout-vendors.js */\nvendors: {\n \u0026quot;vendor1\u0026quot;: {\n \u0026quot;url\u0026quot;: \u0026quot;https://vendor1.com/slot_id=SLOT_ID\u0026quot;,\n \u0026quot;macros\u0026quot;: ['SLOT_ID'],\n \u0026quot;errorReportingUrl\u0026quot;: \u0026quot;https://vendor1.com/e=ERROR_TYPE\u0026amp;h=HREF\u0026quot;,\n }\n};\"\u003e\u003cpre lang=\"text\" class=\"notranslate\"\u003e\u003ccode\u003e/** amp-a4a/0.1/callout-vendors.js */\nvendors: {\n \"vendor1\": {\n \"url\": \"https://vendor1.com/slot_id=SLOT_ID\",\n \"macros\": ['SLOT_ID'],\n \"errorReportingUrl\": \"https://vendor1.com/e=ERROR_TYPE\u0026amp;h=HREF\",\n }\n};\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe only valid strings that can be replaced for a given URL are specified by the \u003ccode\u003emacros\u003c/code\u003e array. In the above example, the only valid macro to replace in \u003ccode\u003ehttps://vendor1.com/slot_id=SLOT_ID\u003c/code\u003e is \u003ccode\u003e\"SLOT_ID\"\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe \u003ccode\u003emacros\u003c/code\u003e attribute is optional, i.e. a vendor could specify a URL that has no macros to substitute in.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eAdditionally, macros can be substituted in by the Fast Fetch implementation itself. The URL for a vendor will be expanded with the correct macro values prior to callout. See \u003ca href=\"#url-macro-substitution\"\u003eURL Macro Substitution\u003c/a\u003e section below for detailed explanation and example.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe \u003ccode\u003eerrorReportingUrl\u003c/code\u003e property is optional. The only available macros are ERROR_TYPE and HREF. See \u003ca href=\"#rtc-error-pingback\"\u003eRTC Error Pingback\u003c/a\u003e section below for more information on how error reporting works.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eCurrently Supported Vendors\u003c/h4\u003e\u003ca id=\"user-content-currently-supported-vendors\" class=\"anchor\" aria-label=\"Permalink: Currently Supported Vendors\" href=\"#currently-supported-vendors\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eAdmax\u003c/li\u003e\n\u003cli\u003eAdpushup\u003c/li\u003e\n\u003cli\u003eAppNexus PSP\u003c/li\u003e\n\u003cli\u003eAPS\u003c/li\u003e\n\u003cli\u003eAutomatad\u003c/li\u003e\n\u003cli\u003eAndbeyond\u003c/li\u003e\n\u003cli\u003eBrowsi\u003c/li\u003e\n\u003cli\u003eCriteo\u003c/li\u003e\n\u003cli\u003eDenakop\u003c/li\u003e\n\u003cli\u003eFLUX\u003c/li\u003e\n\u003cli\u003eFreestar\u003c/li\u003e\n\u003cli\u003eFuture Plc\u003c/li\u003e\n\u003cli\u003eGalaxie Media\u003c/li\u003e\n\u003cli\u003eHighfivve\u003c/li\u003e\n\u003cli\u003eHubvisor\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://www.improvedigital.com\" rel=\"nofollow\"\u003eImprove Digital\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eIndexExchange\u003c/li\u003e\n\u003cli\u003eKargo\u003c/li\u003e\n\u003cli\u003eLotame\u003c/li\u003e\n\u003cli\u003eMedia.net\u003c/li\u003e\n\u003cli\u003eMediasquare\u003c/li\u003e\n\u003cli\u003eNavegg\u003c/li\u003e\n\u003cli\u003eNewsPassID\u003c/li\u003e\n\u003cli\u003eNexx360.io\u003c/li\u003e\n\u003cli\u003eOpenX\u003c/li\u003e\n\u003cli\u003ePubMatic OpenWrap\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://www.pubwise.io\" rel=\"nofollow\"\u003ePubWise\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003ePurch\u003c/li\u003e\n\u003cli\u003eRichAudience\u003c/li\u003e\n\u003cli\u003eRubicon\u003c/li\u003e\n\u003cli\u003eSalesforce\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://www.snigel.com\" rel=\"nofollow\"\u003eSnigel\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eSonobi\u003c/li\u003e\n\u003cli\u003eT13\u003c/li\u003e\n\u003cli\u003eTail\u003c/li\u003e\n\u003cli\u003eThe Ozone Project\u003c/li\u003e\n\u003cli\u003eYieldbot\u003c/li\u003e\n\u003cli\u003eYieldlab\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eRTC Callout Request Specification\u003c/h3\u003e\u003ca id=\"user-content-rtc-callout-request-specification\" class=\"anchor\" aria-label=\"Permalink: RTC Callout Request Specification\" href=\"#rtc-callout-request-specification\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eRTC callout requests are sent from the AMP runtime with the following headers:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eAccept: application/JSON\u003c/li\u003e\n\u003cli\u003eOrigin: Whatever the origin of the page is.\u003c/li\u003e\n\u003cli\u003eReferer: Referer URL\u003c/li\u003e\n\u003cli\u003eUser-Agent: Standard user-agent information\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eAdditionally, query string parameters are optionally sent as per the specification of the URL.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eRTC requests are sent using the \u003ca href=\"https://github.com/ampproject/amphtml/blob/main/src/service/xhr-impl.js#L213\"\u003efetchJson method defined in xhr-impl.js.\u003c/a\u003e For RTC, in practice this is a GET request.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eRTC requests are only sent to HTTPS endpoints.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eRTC Callout Endpoint and Response Specification\u003c/h3\u003e\u003ca id=\"user-content-rtc-callout-endpoint-and-response-specification\" class=\"anchor\" aria-label=\"Permalink: RTC Callout Endpoint and Response Specification\" href=\"#rtc-callout-endpoint-and-response-specification\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe RTC endpoint must respond to the RTC GET request with a valid JSON object of targeting information to insert into the ad request URL. Redirects are not allowed, and if the endpoint attempts to redirect, the RTC will be abandoned. Special care should be made to respond to these requests as quickly as possible, as there is a 1 second default timeout imposed by RTC, and publishers may optionally shorten this timeout. Responses that return after the timeout will be dropped.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eResponses from one RTC callout do not affect any of the other RTC callouts. All requests are independent of each other.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe RTC callout endpoint must use HTTPS. HTTP requests are forbidden.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe RTC Response to a GET request must meet the following requirements:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eStatus Code = 200\u003c/li\u003e\n\u003cli\u003eSee \u003ca href=\"https://github.com/ampproject/amphtml/blob/main/docs/spec/amp-cors-requests.md#ensuring-secure-responses\"\u003ehere for Required Headers\u003c/a\u003e and note that Access-Control-Allow-Credentials: true must be present for cookies to be included in the request.\u003c/li\u003e\n\u003cli\u003eBody of response is a JSON object of targeting information such as:\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ccode\u003e{\"targeting\": {\"sport\":[\"rugby\",\"cricket\"]}}\u003c/code\u003e\u003c/strong\u003e\u003c/li\u003e\n\u003cli\u003eThe response body must be JSON, but the actual structure of that data need not match the structure here. Refer to Fast Fetch Network specific documentation for the required spec. (for example, if using DoubleClick, refer to DoubleClick docs).\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eRTC Error Pingback\u003c/h3\u003e\u003ca id=\"user-content-rtc-error-pingback\" class=\"anchor\" aria-label=\"Permalink: RTC Error Pingback\" href=\"#rtc-error-pingback\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eRTC supports sending a 1% per-page sampling of RTC errors to specified errorReportingUrl's. (I.e. 1% of pages will send RTC error pingbacks for all RTC errors that occur on that page). For any given RTC callout URL, a corresponding errorReportingUrl may be specified, which will receive pings for, and only for, errors that resulted from the associated RTC callout. For example, you can not specify one errorReportingUrl that receives batched pings for all RTC callouts from a page. The errorReportingUrl must be a secure URL that uses HTTPS.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eVendors may specify an errorReportingUrl within their config in callout-vendors.js, e.g.:\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"/** amp-a4a/0.1/callout-vendors.js */\nvendors: {\n \u0026quot;vendor1\u0026quot;: {\n \u0026quot;url\u0026quot;: \u0026quot;https://vendor1.com/slot_id=SLOT_ID\u0026quot;,\n \u0026quot;macros\u0026quot;: ['SLOT_ID'],\n \u0026quot;errorReportingUrl\u0026quot;: \u0026quot;https://vendor1.com/e=ERROR_TYPE\u0026amp;h=HREF\u0026quot;,\n }\n};\"\u003e\u003cpre lang=\"text\" class=\"notranslate\"\u003e\u003ccode\u003e/** amp-a4a/0.1/callout-vendors.js */\nvendors: {\n \"vendor1\": {\n \"url\": \"https://vendor1.com/slot_id=SLOT_ID\",\n \"macros\": ['SLOT_ID'],\n \"errorReportingUrl\": \"https://vendor1.com/e=ERROR_TYPE\u0026amp;h=HREF\",\n }\n};\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eFor custom URLs specified by a publisher directly on the RTC Config, they specify the errorReportingUrl by setting values in the \"url\" array as an object, instead of a string, e.g.:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-text-html-basic notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"\u0026lt;amp-ad\n width=\u0026quot;320\u0026quot;\n height=\u0026quot;50\u0026quot;\n type=\u0026quot;network-foo\u0026quot;\n data-slot=\u0026quot;/1234/5678\u0026quot;\n rtc-config='{\n \u0026quot;vendors\u0026quot;: {\n \u0026quot;vendorA\u0026quot;: {\u0026quot;SLOT_ID\u0026quot;: \u0026quot;1\u0026quot;},\n },\n \u0026quot;urls\u0026quot;: [\n \u0026quot;https://www.AmpPublisher.biz/targetingA\u0026quot;,\n {\u0026quot;url\u0026quot;: \u0026quot;https://www.AmpPublisher.biz/targetingB\u0026quot;,\n \u0026quot;errorReportingUrl\u0026quot;: \u0026quot;https://www.AmpPublisher.biz?e=ERROR_TYPE\u0026amp;h=HREF\u0026quot;}\n ],\n \u0026quot;timeoutMillis\u0026quot;: 750}'\n\u0026gt;\n\u0026lt;/amp-ad\u0026gt;\"\u003e\u003cpre\u003e\u003cspan class=\"pl-kos\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003eamp-ad\u003c/span\u003e\n \u003cspan class=\"pl-c1\"\u003ewidth\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e320\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003eheight\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e50\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003etype\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003enetwork-foo\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003edata-slot\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e/1234/5678\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003ertc-config\u003c/span\u003e='\u003cspan class=\"pl-s\"\u003e{\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendors\": {\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendorA\": {\"SLOT_ID\": \"1\"},\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e },\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"urls\": [\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"https://www.AmpPublisher.biz/targetingA\",\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e {\"url\": \"https://www.AmpPublisher.biz/targetingB\",\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"errorReportingUrl\": \"https://www.AmpPublisher.biz?e=ERROR_TYPE\u0026amp;h=HREF\"}\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e ],\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"timeoutMillis\": 750}\u003c/span\u003e'\n\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003eamp-ad\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIn both cases, the requirements for an errorReportingUrl are the same:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eerrorReportingUrl must use HTTPS.\u003c/li\u003e\n\u003cli\u003eResponse should be an empty 200.\u003c/li\u003e\n\u003cli\u003eerrorReportingUrl may utilize two available macros that will be substituted in:\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003cstrong\u003eERROR_TYPE\u003c/strong\u003e - Will be sent as an enum value that corresponds to values in \u003ccode\u003eRTC_ERROR_ENUM\u003c/code\u003e found in \u003ca href=\"https://github.com/ampproject/amphtml/blob/main/src/service/real-time-config/real-time-config-impl.js\"\u003ereal-time-config-impl.js\u003c/a\u003e.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eHREF\u003c/strong\u003e - The actual full URL of the page. Equivalent to historical value of AMP's window.context.location.href.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eThe error ping will be sent by creating an image pixel in the document. See \u003ccode\u003esendErrorMessage\u003c/code\u003e in \u003ca href=\"https://github.com/ampproject/amphtml/blob/main/src/service/real-time-config/real-time-config-impl.js\"\u003ereal-time-config-impl.js\u003c/a\u003e for implementation details.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eAMP Consent Integration\u003c/h3\u003e\u003ca id=\"user-content-amp-consent-integration\" class=\"anchor\" aria-label=\"Permalink: AMP Consent Integration\" href=\"#amp-consent-integration\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe AMP-Consent extension provides publishers the ability to collect and store a user's consent through a UI control, while also providing the ability to block other AMP components based on the user's consent. See \u003ca href=\"https://github.com/ampproject/amphtml/blob/main/extensions/amp-consent/amp-consent.md\"\u003ehere for documentation\u003c/a\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eReal Time Config supports integration with AMP-Consent. If the AMP-consent response is neither \u003ccode\u003eSUFFICIENT\u003c/code\u003e nor \u003ccode\u003eUNKNOWN_NOT_REQUIRED\u003c/code\u003e, then by default all RTC callouts are suppressed. However, you may optionally modify this setting, to allow specific RTC callouts that should be sent regardless of the consent state. A publisher can modify this across all RTC requests for a given ad slot or on a per-RTC-callout basis. A publisher also may either permit all consent states, or only specific consent states, using the RTC Config attribute \u003ccode\u003esendRegardlessOfConsentState\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe value of \u003ccode\u003esendRegardlessOfConsentState\u003c/code\u003e should either be the boolean \u003ccode\u003etrue\u003c/code\u003e or an array of consent policy state strings as defined in src/core/constants/consent-state.js (i.e. use the string keys, like\u003ccode\u003e\"UNKNOWN\"\u003c/code\u003e not its corresponding numeric value). In a case where the RTC callout would normally be supressed (for example if the AMP-consent response is \u003ccode\u003eUNKNOWN\u003c/code\u003e), it will instead be sent if \u003ccode\u003esendRegardlessOfConsentState\u003c/code\u003e is set to boolean \u003ccode\u003etrue\u003c/code\u003e or an array of values that contains a match for the AMP-consent state response (e.g. \u003ccode\u003e['UNKNOWN']\u003c/code\u003e). If set to an array, then only the values in that array (in addition to the defualt values of \u003ccode\u003eSUFFICIENT\u003c/code\u003e and \u003ccode\u003eUNKNOWN_NOT_REQUIRED\u003c/code\u003e) are treated as valid.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe setting of \u003ccode\u003esendRegardlessOfConsentState\u003c/code\u003e can either be done once for the entire ad slot by setting it as a top-level attribute on the RTC Config, or be done individually by setting it on any individual callouts as needed. If it is set at both the top-level and per-callout level, then if there is a mismatch, the per-callout level \"wins\". This is detailed below in the examples.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eHere are various examples of how to do this for any given ad slot:\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eAllow all RTC callouts for all consent states\u003c/h4\u003e\u003ca id=\"user-content-allow-all-rtc-callouts-for-all-consent-states\" class=\"anchor\" aria-label=\"Permalink: Allow all RTC callouts for all consent states\" href=\"#allow-all-rtc-callouts-for-all-consent-states\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-text-html-basic notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"\u0026lt;amp-ad\n width=\u0026quot;320\u0026quot;\n height=\u0026quot;50\u0026quot;\n type=\u0026quot;network-foo\u0026quot;\n data-slot=\u0026quot;/1234/5678\u0026quot;\n rtc-config='{\n \u0026quot;vendors\u0026quot;: {\n \u0026quot;vendorA\u0026quot;: {\u0026quot;SLOT_ID\u0026quot;: \u0026quot;1\u0026quot;},\n \u0026quot;vendorB\u0026quot;: {\u0026quot;PAGE_ID\u0026quot;: \u0026quot;2\u0026quot;},\n \u0026quot;vendorC\u0026quot;: {\u0026quot;SLOT_W\u0026quot;: \u0026quot;320\u0026quot;, \u0026quot;SLOT_H\u0026quot;: \u0026quot;50\u0026quot;}\n },\n \u0026quot;urls\u0026quot;: [\n \u0026quot;https://www.AmpPublisher.biz/targetingA\u0026quot;,\n \u0026quot;https://www.AmpPublisher.biz/targetingB\u0026quot;\n ],\n \u0026quot;sendRegardlessOfConsentState\u0026quot;: true}'\n\u0026gt;\n\u0026lt;/amp-ad\u0026gt;\"\u003e\u003cpre\u003e\u003cspan class=\"pl-kos\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003eamp-ad\u003c/span\u003e\n \u003cspan class=\"pl-c1\"\u003ewidth\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e320\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003eheight\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e50\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003etype\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003enetwork-foo\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003edata-slot\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e/1234/5678\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003ertc-config\u003c/span\u003e='\u003cspan class=\"pl-s\"\u003e{\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendors\": {\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendorA\": {\"SLOT_ID\": \"1\"},\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendorB\": {\"PAGE_ID\": \"2\"},\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendorC\": {\"SLOT_W\": \"320\", \"SLOT_H\": \"50\"}\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e },\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"urls\": [\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"https://www.AmpPublisher.biz/targetingA\",\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"https://www.AmpPublisher.biz/targetingB\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e ],\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"sendRegardlessOfConsentState\": true}\u003c/span\u003e'\n\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003eamp-ad\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eBy setting \u003ccode\u003esendRegardlessOfConsentState\u003c/code\u003e at top-level to \u003ccode\u003etrue\u003c/code\u003e, this indicates that for any consent state, all of the callouts in this RTC configuration should still be sent.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eAllow all RTC callouts for only certain consent states\u003c/h4\u003e\u003ca id=\"user-content-allow-all-rtc-callouts-for-only-certain-consent-states\" class=\"anchor\" aria-label=\"Permalink: Allow all RTC callouts for only certain consent states\" href=\"#allow-all-rtc-callouts-for-only-certain-consent-states\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-text-html-basic notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"\u0026lt;amp-ad\n width=\u0026quot;320\u0026quot;\n height=\u0026quot;50\u0026quot;\n type=\u0026quot;network-foo\u0026quot;\n data-slot=\u0026quot;/1234/5678\u0026quot;\n rtc-config='{\n \u0026quot;vendors\u0026quot;: {\n \u0026quot;vendorA\u0026quot;: {\u0026quot;SLOT_ID\u0026quot;: \u0026quot;1\u0026quot;},\n \u0026quot;vendorB\u0026quot;: {\u0026quot;PAGE_ID\u0026quot;: \u0026quot;2\u0026quot;},\n \u0026quot;vendorC\u0026quot;: {\u0026quot;SLOT_W\u0026quot;: \u0026quot;320\u0026quot;, \u0026quot;SLOT_H\u0026quot;: \u0026quot;50\u0026quot;}\n },\n \u0026quot;urls\u0026quot;: [\n \u0026quot;https://www.AmpPublisher.biz/targetingA\u0026quot;,\n \u0026quot;https://www.AmpPublisher.biz/targetingB\u0026quot;\n ],\n \u0026quot;sendRegardlessOfConsentState\u0026quot;: [\u0026quot;UNKNOWN\u0026quot;]}'\n\u0026gt;\n\u0026lt;/amp-ad\u0026gt;\"\u003e\u003cpre\u003e\u003cspan class=\"pl-kos\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003eamp-ad\u003c/span\u003e\n \u003cspan class=\"pl-c1\"\u003ewidth\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e320\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003eheight\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e50\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003etype\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003enetwork-foo\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003edata-slot\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e/1234/5678\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003ertc-config\u003c/span\u003e='\u003cspan class=\"pl-s\"\u003e{\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendors\": {\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendorA\": {\"SLOT_ID\": \"1\"},\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendorB\": {\"PAGE_ID\": \"2\"},\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendorC\": {\"SLOT_W\": \"320\", \"SLOT_H\": \"50\"}\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e },\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"urls\": [\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"https://www.AmpPublisher.biz/targetingA\",\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"https://www.AmpPublisher.biz/targetingB\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e ],\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"sendRegardlessOfConsentState\": [\"UNKNOWN\"]}\u003c/span\u003e'\n\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003eamp-ad\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eBy setting \u003ccode\u003esendRegardlessOfConsentState\u003c/code\u003e to an array, this indicates that only when the page consent state matches any of the consent states in the array (in this case only \u003ccode\u003eUNKNOWN\u003c/code\u003e in addition to the default states \u003ccode\u003eSUFFICIENT\u003c/code\u003e and \u003ccode\u003eUNKNOWN_NOT_REQUIRED\u003c/code\u003e) should all of the RTC callouts still be sent. For instance, if the page state is \u003ccode\u003eINSUFFICIENT\u003c/code\u003e, then none of the callout specified above will be sent. If the page state is \u003ccode\u003eUNKNOWN\u003c/code\u003e, then all of the callouts will be sent.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eAllow some RTC callouts in the \"url\" array\u003c/h4\u003e\u003ca id=\"user-content-allow-some-rtc-callouts-in-the-url-array\" class=\"anchor\" aria-label=\"Permalink: Allow some RTC callouts in the \u0026quot;url\u0026quot; array\" href=\"#allow-some-rtc-callouts-in-the-url-array\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-text-html-basic notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"\u0026lt;amp-ad\n width=\u0026quot;320\u0026quot;\n height=\u0026quot;50\u0026quot;\n type=\u0026quot;network-foo\u0026quot;\n data-slot=\u0026quot;/1234/5678\u0026quot;\n rtc-config='{\n \u0026quot;vendors\u0026quot;: {\n \u0026quot;vendorA\u0026quot;: {\u0026quot;SLOT_ID\u0026quot;: \u0026quot;1\u0026quot;},\n \u0026quot;vendorB\u0026quot;: {\u0026quot;PAGE_ID\u0026quot;: \u0026quot;2\u0026quot;},\n \u0026quot;vendorC\u0026quot;: {\u0026quot;SLOT_W\u0026quot;: \u0026quot;320\u0026quot;, \u0026quot;SLOT_H\u0026quot;: \u0026quot;50\u0026quot;}\n },\n \u0026quot;urls\u0026quot;: [\n {\u0026quot;url\u0026quot;: \u0026quot;https://www.AmpPublisher.biz/targetingA\u0026quot;,\n \u0026quot;sendRegardlessOfConsentState\u0026quot;: true},\n \u0026quot;https://www.AmpPublisher.biz/targetingB\u0026quot;\n ]}'\n\u0026gt;\n\u0026lt;/amp-ad\u0026gt;\"\u003e\u003cpre\u003e\u003cspan class=\"pl-kos\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003eamp-ad\u003c/span\u003e\n \u003cspan class=\"pl-c1\"\u003ewidth\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e320\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003eheight\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e50\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003etype\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003enetwork-foo\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003edata-slot\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e/1234/5678\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003ertc-config\u003c/span\u003e='\u003cspan class=\"pl-s\"\u003e{\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendors\": {\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendorA\": {\"SLOT_ID\": \"1\"},\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendorB\": {\"PAGE_ID\": \"2\"},\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendorC\": {\"SLOT_W\": \"320\", \"SLOT_H\": \"50\"}\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e },\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"urls\": [\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e {\"url\": \"https://www.AmpPublisher.biz/targetingA\",\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"sendRegardlessOfConsentState\": true},\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"https://www.AmpPublisher.biz/targetingB\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e ]}\u003c/span\u003e'\n\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003eamp-ad\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIn this example, \u003ccode\u003esendRegardlessOfConsentState\u003c/code\u003e is only set for one specific URL, the first URL in the array \"urls\". Take the case when the page state is \u003ccode\u003eUNKNOWN\u003c/code\u003e. In that case, the only RTC callout that would be sent is the one to \u003ccode\u003ehttps://www.AmpPublisher.biz/targetingA\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIs is also possible to set \u003ccode\u003esendRegardlessOfConsentState\u003c/code\u003e here to an array as well, such as:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-text-html-basic notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"\u0026lt;amp-ad\n width=\u0026quot;320\u0026quot;\n height=\u0026quot;50\u0026quot;\n type=\u0026quot;network-foo\u0026quot;\n data-slot=\u0026quot;/1234/5678\u0026quot;\n rtc-config='{\n \u0026quot;vendors\u0026quot;: {\n \u0026quot;vendorA\u0026quot;: {\u0026quot;SLOT_ID\u0026quot;: \u0026quot;1\u0026quot;},\n \u0026quot;vendorB\u0026quot;: {\u0026quot;PAGE_ID\u0026quot;: \u0026quot;2\u0026quot;},\n \u0026quot;vendorC\u0026quot;: {\u0026quot;SLOT_W\u0026quot;: \u0026quot;320\u0026quot;, \u0026quot;SLOT_H\u0026quot;: \u0026quot;50\u0026quot;}\n },\n \u0026quot;urls\u0026quot;: [\n {\u0026quot;url\u0026quot;: \u0026quot;https://www.AmpPublisher.biz/targetingA\u0026quot;,\n \u0026quot;sendRegardlessOfConsentState\u0026quot;: [\u0026quot;UNKNOWN\u0026quot;, \u0026quot;INSUFFICIENT\u0026quot;]},\n \u0026quot;https://www.AmpPublisher.biz/targetingB\u0026quot;\n ]}'\n\u0026gt;\n\u0026lt;/amp-ad\u0026gt;\"\u003e\u003cpre\u003e\u003cspan class=\"pl-kos\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003eamp-ad\u003c/span\u003e\n \u003cspan class=\"pl-c1\"\u003ewidth\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e320\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003eheight\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e50\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003etype\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003enetwork-foo\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003edata-slot\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e/1234/5678\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003ertc-config\u003c/span\u003e='\u003cspan class=\"pl-s\"\u003e{\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendors\": {\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendorA\": {\"SLOT_ID\": \"1\"},\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendorB\": {\"PAGE_ID\": \"2\"},\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendorC\": {\"SLOT_W\": \"320\", \"SLOT_H\": \"50\"}\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e },\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"urls\": [\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e {\"url\": \"https://www.AmpPublisher.biz/targetingA\",\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"sendRegardlessOfConsentState\": [\"UNKNOWN\", \"INSUFFICIENT\"]},\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"https://www.AmpPublisher.biz/targetingB\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e ]}\u003c/span\u003e'\n\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003eamp-ad\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eAllow some RTC callouts in the \"vendors\" object\u003c/h4\u003e\u003ca id=\"user-content-allow-some-rtc-callouts-in-the-vendors-object\" class=\"anchor\" aria-label=\"Permalink: Allow some RTC callouts in the \u0026quot;vendors\u0026quot; object\" href=\"#allow-some-rtc-callouts-in-the-vendors-object\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-text-html-basic notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"\u0026lt;amp-ad\n width=\u0026quot;320\u0026quot;\n height=\u0026quot;50\u0026quot;\n type=\u0026quot;network-foo\u0026quot;\n data-slot=\u0026quot;/1234/5678\u0026quot;\n rtc-config='{\n \u0026quot;vendors\u0026quot;: {\n \u0026quot;vendorA\u0026quot;: {\u0026quot;macros\u0026quot; {\u0026quot;SLOT_ID\u0026quot;: \u0026quot;1\u0026quot;},\n \u0026quot;sendRegardlessOfConsentState\u0026quot;: [\u0026quot;UNKNOWN\u0026quot;]},\n \u0026quot;vendorB\u0026quot;: {\u0026quot;PAGE_ID\u0026quot;: \u0026quot;2\u0026quot;},\n \u0026quot;vendorC\u0026quot;: {\u0026quot;SLOT_W\u0026quot;: \u0026quot;320\u0026quot;, \u0026quot;SLOT_H\u0026quot;: \u0026quot;50\u0026quot;}\n },\n \u0026quot;urls\u0026quot;: [\n \u0026quot;https://www.AmpPublisher.biz/targetingA\u0026quot;,\n \u0026quot;https://www.AmpPublisher.biz/targetingB\u0026quot;\n ]}'\n\u0026gt;\n\u0026lt;/amp-ad\u0026gt;\"\u003e\u003cpre\u003e\u003cspan class=\"pl-kos\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003eamp-ad\u003c/span\u003e\n \u003cspan class=\"pl-c1\"\u003ewidth\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e320\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003eheight\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e50\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003etype\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003enetwork-foo\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003edata-slot\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e/1234/5678\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003ertc-config\u003c/span\u003e='\u003cspan class=\"pl-s\"\u003e{\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendors\": {\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendorA\": {\"macros\" {\"SLOT_ID\": \"1\"},\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"sendRegardlessOfConsentState\": [\"UNKNOWN\"]},\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendorB\": {\"PAGE_ID\": \"2\"},\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendorC\": {\"SLOT_W\": \"320\", \"SLOT_H\": \"50\"}\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e },\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"urls\": [\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"https://www.AmpPublisher.biz/targetingA\",\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"https://www.AmpPublisher.biz/targetingB\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e ]}\u003c/span\u003e'\n\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003eamp-ad\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIn this example, \u003ccode\u003esendRegardlessOfConsentState\u003c/code\u003e is only set for one specific URL, the first vendor in the \"vendors\" object. Take the case when the page state is \u003ccode\u003eUNKNOWN\u003c/code\u003e. In that case, the only RTC callout that would be sent is the one to vendorA.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eMixture of settings\u003c/h4\u003e\u003ca id=\"user-content-mixture-of-settings\" class=\"anchor\" aria-label=\"Permalink: Mixture of settings\" href=\"#mixture-of-settings\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-text-html-basic notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"\u0026lt;amp-ad\n width=\u0026quot;320\u0026quot;\n height=\u0026quot;50\u0026quot;\n type=\u0026quot;network-foo\u0026quot;\n data-slot=\u0026quot;/1234/5678\u0026quot;\n rtc-config='{\n \u0026quot;vendors\u0026quot;: {\n \u0026quot;vendorA\u0026quot;: {\u0026quot;macros\u0026quot; {\u0026quot;SLOT_ID\u0026quot;: \u0026quot;1\u0026quot;},\n \u0026quot;sendRegardlessOfConsentState\u0026quot;: [\u0026quot;INSUFFICIENT\u0026quot;]},\n \u0026quot;vendorB\u0026quot;: {\u0026quot;PAGE_ID\u0026quot;: \u0026quot;2\u0026quot;},\n \u0026quot;vendorC\u0026quot;: {\u0026quot;SLOT_W\u0026quot;: \u0026quot;320\u0026quot;, \u0026quot;SLOT_H\u0026quot;: \u0026quot;50\u0026quot;}\n },\n \u0026quot;urls\u0026quot;: [\n {\u0026quot;url\u0026quot;: \u0026quot;https://www.AmpPublisher.biz/targetingA\u0026quot;,\n \u0026quot;sendRegardlessOfConsentState\u0026quot;: [\u0026quot;UNKNOWN\u0026quot;]},\n \u0026quot;https://www.AmpPublisher.biz/targetingB\u0026quot;\n ],\n \u0026quot;sendRegardlessOfConsentState\u0026quot;: true}'\n\u0026gt;\n\u0026lt;/amp-ad\u0026gt;\"\u003e\u003cpre\u003e\u003cspan class=\"pl-kos\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003eamp-ad\u003c/span\u003e\n \u003cspan class=\"pl-c1\"\u003ewidth\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e320\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003eheight\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e50\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003etype\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003enetwork-foo\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003edata-slot\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e/1234/5678\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003ertc-config\u003c/span\u003e='\u003cspan class=\"pl-s\"\u003e{\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendors\": {\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendorA\": {\"macros\" {\"SLOT_ID\": \"1\"},\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"sendRegardlessOfConsentState\": [\"INSUFFICIENT\"]},\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendorB\": {\"PAGE_ID\": \"2\"},\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendorC\": {\"SLOT_W\": \"320\", \"SLOT_H\": \"50\"}\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e },\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"urls\": [\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e {\"url\": \"https://www.AmpPublisher.biz/targetingA\",\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"sendRegardlessOfConsentState\": [\"UNKNOWN\"]},\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"https://www.AmpPublisher.biz/targetingB\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e ],\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"sendRegardlessOfConsentState\": true}\u003c/span\u003e'\n\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003eamp-ad\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIn this example, we have a mixture of various settings. In addition to all the callouts allowing the default states \u003ccode\u003eSUFFICIENT\u003c/code\u003e and \u003ccode\u003eUNKNOWN_NOT_REQUIRED\u003c/code\u003e, VendorA is set to allow page consent-state \u003ccode\u003eINSUFFICIENT\u003c/code\u003e, the first url in the \u003ccode\u003eurls\u003c/code\u003e array only state \u003ccode\u003eUNKNOWN\u003c/code\u003e, and the top-level setting across all the RTC callouts is set to \u003ccode\u003etrue\u003c/code\u003e, indicating that we should send all RTC callouts regardless of consent-state. How do we reconcile these various values? As explained above, in the case where a top-level setting and a per-callout setting disagree, the per-callout setting wins.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eLet's first take an example where the page consent-state is \u003ccode\u003eSUFFICIENT\u003c/code\u003e. This is a default allowed state, so trivially all the callouts will be sent.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eNext, let's take an example where the page consent-state is \u003ccode\u003eUNKNOWN\u003c/code\u003e. The callout to vendorA is set to allow consent-state \u003ccode\u003eINSUFFICIENT\u003c/code\u003e, so it will not be sent. The callouts to vendorB and vendorC do not have individual \u003ccode\u003esendRegardlessOfConsentState\u003c/code\u003e settings, so the top-level setting of \u003ccode\u003etrue\u003c/code\u003e applies to them, and they will each be sent. In the \u003ccode\u003eurls\u003c/code\u003e array, the first URL has an individual setting of \u003ccode\u003eUNKNOWN\u003c/code\u003e, which is the current state, so it will be sent. Lastly, the final url does not have an individual setting, so the top-level setting of \u003ccode\u003etrue\u003c/code\u003e applies to it, and it will be sent.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eBlocking RTC\u003c/h3\u003e\u003ca id=\"user-content-blocking-rtc\" class=\"anchor\" aria-label=\"Permalink: Blocking RTC\" href=\"#blocking-rtc\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe \u003ccode\u003eblock-rtc\u003c/code\u003e provides a way to utilize the \u003ccode\u003e\u0026lt;amp-geo\u0026gt;\u003c/code\u003e component to detect user's geo location to decide if a RTC callout should be prevented. The value of \u003ccode\u003eblock-rtc\u003c/code\u003e should be a comma delimited string of geo group codes which are defined in \u003ccode\u003e\u0026lt;amp-geo\u0026gt;\u003c/code\u003e (details \u003ca href=\"https://github.com/ampproject/amphtml/blob/main/extensions/amp-geo/amp-geo.md\"\u003ehere\u003c/a\u003e). If no \u003ccode\u003e\u0026lt;amp-geo\u0026gt;\u003c/code\u003e element is found or no valid value for this attribute, then the RTC callout will occur as normal.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-text-html-basic notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"\u0026lt;amp-ad\n width=\u0026quot;300\u0026quot;\n height=\u0026quot;200\u0026quot;\n type=\u0026quot;network-foo\u0026quot;\n data-slot=\u0026quot;/1234/5678\u0026quot;\n block-rtc=\u0026quot;geoGroup1,geoGroup2\u0026quot;\n rtc-config='{\n \u0026quot;vendors\u0026quot;: {\n \u0026quot;vendorA\u0026quot;: {\u0026quot;SLOT_ID\u0026quot;: \u0026quot;1\u0026quot;},\n \u0026quot;vendorB\u0026quot;: {\u0026quot;PAGE_ID\u0026quot;: \u0026quot;2\u0026quot;},\n \u0026quot;vendorC\u0026quot;: {\u0026quot;SLOT_W\u0026quot;: \u0026quot;320\u0026quot;, \u0026quot;SLOT_H\u0026quot;: \u0026quot;50\u0026quot;}\n },\n \u0026quot;urls\u0026quot;: [\n \u0026quot;https://www.AmpPublisher.biz/targetingA\u0026quot;,\n \u0026quot;https://www.AmpPublisher.biz/targetingB\u0026quot;\n ],\n \u0026quot;sendRegardlessOfConsentState\u0026quot;: true}'\n\u0026gt;\n\u0026lt;/amp-ad\u0026gt;\n\n\u0026lt;amp-geo\u0026gt;\n \u0026lt;script type=\u0026quot;application/json\u0026quot;\u0026gt;\n {\n \u0026quot;ISOCountryGroups\u0026quot;: {\n \u0026quot;geoGroup1\u0026quot;: [ \u0026quot;preset-eea\u0026quot;, \u0026quot;unknown\u0026quot; ],\n \u0026quot;geoGroup2\u0026quot;: [ \u0026quot;preset-us-ca\u0026quot; ]\n }\n }\n \u0026lt;/script\u0026gt;\n\u0026lt;/amp-geo\u0026gt;\"\u003e\u003cpre\u003e\u003cspan class=\"pl-kos\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003eamp-ad\u003c/span\u003e\n \u003cspan class=\"pl-c1\"\u003ewidth\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e300\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003eheight\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e200\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003etype\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003enetwork-foo\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003edata-slot\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e/1234/5678\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003eblock-rtc\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003egeoGroup1,geoGroup2\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003ertc-config\u003c/span\u003e='\u003cspan class=\"pl-s\"\u003e{\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendors\": {\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendorA\": {\"SLOT_ID\": \"1\"},\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendorB\": {\"PAGE_ID\": \"2\"},\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendorC\": {\"SLOT_W\": \"320\", \"SLOT_H\": \"50\"}\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e },\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"urls\": [\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"https://www.AmpPublisher.biz/targetingA\",\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"https://www.AmpPublisher.biz/targetingB\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e ],\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"sendRegardlessOfConsentState\": true}\u003c/span\u003e'\n\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003eamp-ad\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\n\n\u003cspan class=\"pl-kos\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003eamp-geo\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\n \u003cspan class=\"pl-kos\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003escript\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003etype\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003eapplication/json\u003c/span\u003e\"\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\n \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n \u003cspan class=\"pl-s\"\u003e\"ISOCountryGroups\"\u003c/span\u003e: \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n \u003cspan class=\"pl-s\"\u003e\"geoGroup1\"\u003c/span\u003e: \u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"preset-eea\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"unknown\"\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n \u003cspan class=\"pl-s\"\u003e\"geoGroup2\"\u003c/span\u003e: \u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"preset-us-ca\"\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\n \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n \u003cspan class=\"pl-kos\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003escript\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003eamp-geo\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eURL Macro Substitution\u003c/h3\u003e\u003ca id=\"user-content-url-macro-substitution\" class=\"anchor\" aria-label=\"Permalink: URL Macro Substitution\" href=\"#url-macro-substitution\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eRTC supports macro substitution for building callout URLs. These macros can be specified by vendors, and by Fast Fetch implementations.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eVendor Defined Macros\u003c/h4\u003e\u003ca id=\"user-content-vendor-defined-macros\" class=\"anchor\" aria-label=\"Permalink: Vendor Defined Macros\" href=\"#vendor-defined-macros\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eA vendor can specify macros for substitution in their URL. The only requirement to do this is to include text in their URL in \u003ca href=\"https://github.com/ampproject/amphtml/blob/main/src/service/real-time-config/callout-vendors.js\"\u003ecallout-vendors.js\u003c/a\u003e that is intended to be replaced.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eExample\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"/** amp-a4a/0.1/callout-vendors.js */\nvendors: {\n \u0026quot;vendor1\u0026quot;: {\n \u0026quot;url\u0026quot;: \u0026quot;https://vendor1.com/foo?slot_id=SLOT_ID\u0026quot;,\n \u0026quot;macros\u0026quot;: ['SLOT_ID']\n }\n};\"\u003e\u003cpre lang=\"text\" class=\"notranslate\"\u003e\u003ccode\u003e/** amp-a4a/0.1/callout-vendors.js */\nvendors: {\n \"vendor1\": {\n \"url\": \"https://vendor1.com/foo?slot_id=SLOT_ID\",\n \"macros\": ['SLOT_ID']\n }\n};\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch5 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eExample 2: Use of Vendor URLs\u003c/h5\u003e\u003ca id=\"user-content-example-2-use-of-vendor-urls\" class=\"anchor\" aria-label=\"Permalink: Example 2: Use of Vendor URLs\" href=\"#example-2-use-of-vendor-urls\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIf a publisher wishes to callout to vendor1, then they would specify their RTC config as:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-text-html-basic notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"\u0026lt;amp-ad\n width=\u0026quot;320\u0026quot;\n height=\u0026quot;50\u0026quot;\n type=\u0026quot;network-foo\u0026quot;\n data-slot=\u0026quot;/1234/5678\u0026quot;\n rtc-config='{\n \u0026quot;vendors\u0026quot;: {\n \u0026quot;vendor1\u0026quot;: {\u0026quot;SLOT_ID\u0026quot;: \u0026quot;1234\u0026quot;}\n }\n }'\n\u0026gt;\n\u0026lt;/amp-ad\u0026gt;\"\u003e\u003cpre\u003e\u003cspan class=\"pl-kos\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003eamp-ad\u003c/span\u003e\n \u003cspan class=\"pl-c1\"\u003ewidth\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e320\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003eheight\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e50\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003etype\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003enetwork-foo\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003edata-slot\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e/1234/5678\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003ertc-config\u003c/span\u003e='\u003cspan class=\"pl-s\"\u003e{\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendors\": {\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendor1\": {\"SLOT_ID\": \"1234\"}\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e }\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e }\u003c/span\u003e'\n\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003eamp-ad\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe resulting RTC callout URL will then be, after macro expansion:\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003e\u003ccode\u003ehttps://vendor1.com/foo?slot_id=1234\u003c/code\u003e\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eFast Fetch Implementation Defined Macros\u003c/h4\u003e\u003ca id=\"user-content-fast-fetch-implementation-defined-macros\" class=\"anchor\" aria-label=\"Permalink: Fast Fetch Implementation Defined Macros\" href=\"#fast-fetch-implementation-defined-macros\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIn addition to vendor-defined macros, with publishers specifying the values for substitution, there is also the ability to utilize macros defined by the Fast Fetch implementation. For example, imagine if there is a property, \u003cstrong\u003efooProp,\u003c/strong\u003e of the element \u003cstrong\u003efooEl\u003c/strong\u003e that is only calculated at runtime. A Fast Fetch network that wants to support optionally adding the value of fooProp to RTC callout URLs that it sends can do so by overriding the method \u003ca href=\"https://github.com/ampproject/amphtml/blob/main/extensions/amp-a4a/0.1/amp-a4a.js\"\u003egetCustomRealTimeConfigMacros on AmpA4a \u003c/a\u003ein their Fast Fetch implementation. The method should return a mapping of macros to values or functions that resolve to a value.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch5 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eExample 3: Fast Fetch implementation defined macros\u003c/h5\u003e\u003ca id=\"user-content-example-3-fast-fetch-implementation-defined-macros\" class=\"anchor\" aria-label=\"Permalink: Example 3: Fast Fetch implementation defined macros\" href=\"#example-3-fast-fetch-implementation-defined-macros\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eFor example, Ad Network AmpAdCom overrides the property in their Fast Fetch Implementation:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-js notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"/** amp-ad-network-ampadcom-impl.js */\n\nexport class AmpAdNetworkAmpAdComImpl extends AmpA4A {\n...\n/** @override */\ngetCustomRealTimeConfigMacros() {\n return {\n ‘FOO_PROP’: getElementById(‘fooEl’).getAttribute(‘fooProp’),\n ‘OTHER_PROP’: ‘staticValue’\n }\n}\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e/** amp-ad-network-ampadcom-impl.js */\u003c/span\u003e\n\n\u003cspan class=\"pl-k\"\u003eexport\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eAmpAdNetworkAmpAdComImpl\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eextends\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eAmpA4A\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n...\n\u003cspan class=\"pl-c\"\u003e/** \u003cspan class=\"pl-k\"\u003e@override\u003c/span\u003e */\u003c/span\u003e\n\u003cspan class=\"pl-en\"\u003egetCustomRealTimeConfigMacros\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n \u003cspan class=\"pl-c1\"\u003e‘FOO_PROP’\u003c/span\u003e: \u003cspan class=\"pl-en\"\u003egetElementById\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003e‘fooEl’\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003egetAttribute\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003e‘fooProp’\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n \u003cspan class=\"pl-c1\"\u003e‘OTHER_PROP’\u003c/span\u003e: \u003cspan class=\"pl-s1\"\u003e‘staticValue’\u003c/span\u003e\n \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThen, publishers and vendors alike would be able to specify the macro FOO_PROP in their URL, and the value would be substituted in at runtime by the Fast Fetch implementation.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch5 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eVendor Macro Substitution with Fast Fetch Network Macro Substitution\u003c/h5\u003e\u003ca id=\"user-content-vendor-macro-substitution-with-fast-fetch-network-macro-substitution\" class=\"anchor\" aria-label=\"Permalink: Vendor Macro Substitution with Fast Fetch Network Macro Substitution\" href=\"#vendor-macro-substitution-with-fast-fetch-network-macro-substitution\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIt is possible for a vendor to specify macros in their URL into which the Fast Fetch implementation will substitute values, in addition to their own custom macros that the publisher may specify in the rtc-config. Take the following example:\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch6 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eExample 4\u003c/h6\u003e\u003ca id=\"user-content-example-4\" class=\"anchor\" aria-label=\"Permalink: Example 4\" href=\"#example-4\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eVendor1 wants to allow publishers to substitute in the value of the slot_id, and allow the Fast Fetch network implementation to substitute in the start time. Thus, they define their URL in \u003ca href=\"https://github.com/ampproject/amphtml/blob/main/src/service/real-time-config/callout-vendors.js\"\u003ecallout-vendors.js\u003c/a\u003e as follows. Note, the vendor only lists SLOT_ID in the macros array, even though SLOT_ID and START are both macros in their URL. The macros array is a list of macros that can be utilized by the publisher. Fast Fetch will always attempt to substitute in network-defined macros, regardless of whether they are defined in the macros array.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-js notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"/** amp-a4a/0.1/callout-vendors.js */\nvendors: {\n \u0026quot;vendor1\u0026quot;: {\n \u0026quot;url\u0026quot;: \u0026quot;https://vendor1.com/slot_id=SLOT_ID\u0026amp;start_time=START\u0026quot;,\n \u0026quot;macros\u0026quot;: ['SLOT_ID']\n }\n};\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e/** amp-a4a/0.1/callout-vendors.js */\u003c/span\u003e\nvendors: \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n \u003cspan class=\"pl-s\"\u003e\"vendor1\"\u003c/span\u003e: \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n \u003cspan class=\"pl-s\"\u003e\"url\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\"https://vendor1.com/slot_id=SLOT_ID\u0026amp;start_time=START\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n \u003cspan class=\"pl-s\"\u003e\"macros\"\u003c/span\u003e: \u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e'SLOT_ID'\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\n \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe Fast Fetch implementation has overridden \u003cstrong\u003egetCustomRealTimeConfigMacros\u003c/strong\u003e, and supports the macro 'START', as seen here:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-js notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"/** amp-ad-network-ampadcom-impl.js */\n\nexport class AmpAdNetworkAmpAdComImpl extends AmpA4A {\n...\n/** @override */\ngetCustomRealTimeConfigMacros() {\n return {\n 'START': Date.now()\n }\n}\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e/** amp-ad-network-ampadcom-impl.js */\u003c/span\u003e\n\n\u003cspan class=\"pl-k\"\u003eexport\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eAmpAdNetworkAmpAdComImpl\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eextends\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eAmpA4A\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n...\n\u003cspan class=\"pl-c\"\u003e/** \u003cspan class=\"pl-k\"\u003e@override\u003c/span\u003e */\u003c/span\u003e\n\u003cspan class=\"pl-en\"\u003egetCustomRealTimeConfigMacros\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n \u003cspan class=\"pl-s\"\u003e'START'\u003c/span\u003e: \u003cspan class=\"pl-v\"\u003eDate\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enow\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eFinally, a publisher who wishes to use Vendor1 with AmpAdCom's Fast Fetch implementation defines their rtc-config as:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-text-html-basic notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"\u0026lt;!-- ampPublisher.biz/some/example/page.html --\u0026gt;\n\u0026lt;amp-ad\n width=\u0026quot;320\u0026quot;\n height=\u0026quot;50\u0026quot;\n type=\u0026quot;network-foo\u0026quot;\n data-slot=\u0026quot;/1234/5678\u0026quot;\n rtc-config='{\n \u0026quot;vendors\u0026quot;: {\n \u0026quot;vendor1\u0026quot;: {\u0026quot;SLOT_ID\u0026quot;: \u0026quot;1234\u0026quot;}\n }\n }'\n\u0026gt;\n\u0026lt;/amp-ad\u0026gt;\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u0026lt;!-- ampPublisher.biz/some/example/page.html --\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003eamp-ad\u003c/span\u003e\n \u003cspan class=\"pl-c1\"\u003ewidth\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e320\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003eheight\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e50\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003etype\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003enetwork-foo\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003edata-slot\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e/1234/5678\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003ertc-config\u003c/span\u003e='\u003cspan class=\"pl-s\"\u003e{\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendors\": {\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendor1\": {\"SLOT_ID\": \"1234\"}\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e }\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e }\u003c/span\u003e'\n\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003eamp-ad\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAfter URL macro expansion, the resulting URL is then\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-httpspec notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"https://vendor1.com/slot_id=1234\u0026amp;start_time=1508508227577\"\u003e\u003cpre\u003e\u003cspan class=\"pl-ii\"\u003ehttps://vendor1.com/slot_id=1234\u0026amp;start_time=1508508227577\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch5 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eConflicting macro substitution\u003c/h5\u003e\u003ca id=\"user-content-conflicting-macro-substitution\" class=\"anchor\" aria-label=\"Permalink: Conflicting macro substitution\" href=\"#conflicting-macro-substitution\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIt is possible, but inadvisable, to have a situation where a vendor specifies the same macro as the Fast Fetch network, i.e. in the above example if \u003cstrong\u003egetCustomRealTimeConfigMacros\u003c/strong\u003e was defined as\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-js notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"/** amp-ad-network-ampadcom-impl.js */\n\nexport class AmpAdNetworkAmpAdComImpl extends AmpA4A {\n...\n/** @override */\ngetCustomRealTimeConfigMacros() {\n return {\n 'START': Date.now(),\n 'SLOT_ID': '5678'\n }\n}\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e/** amp-ad-network-ampadcom-impl.js */\u003c/span\u003e\n\n\u003cspan class=\"pl-k\"\u003eexport\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eAmpAdNetworkAmpAdComImpl\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eextends\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eAmpA4A\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n...\n\u003cspan class=\"pl-c\"\u003e/** \u003cspan class=\"pl-k\"\u003e@override\u003c/span\u003e */\u003c/span\u003e\n\u003cspan class=\"pl-en\"\u003egetCustomRealTimeConfigMacros\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n \u003cspan class=\"pl-s\"\u003e'START'\u003c/span\u003e: \u003cspan class=\"pl-v\"\u003eDate\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enow\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n \u003cspan class=\"pl-s\"\u003e'SLOT_ID'\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e'5678'\u003c/span\u003e\n \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThere is a collision in this case, because the Fast Fetch network is specifying a value to substitute for SLOT_ID, but the vendor has declared SLOT_ID as their custom macro, and the publisher is then trying to substitute in '1234' as the value. In a case like this, the Fast Fetch implementation always wins, i.e. the final URL would be:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-httpspec notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"https://vendor1.com/slot_id=5678\u0026amp;start_time=1508508227577\"\u003e\u003cpre\u003e\u003cspan class=\"pl-ii\"\u003ehttps://vendor1.com/slot_id=5678\u0026amp;start_time=1508508227577\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eRTC Callout Result Merging\u003c/h3\u003e\u003ca id=\"user-content-rtc-callout-result-merging\" class=\"anchor\" aria-label=\"Permalink: RTC Callout Result Merging\" href=\"#rtc-callout-result-merging\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe merging of the results of the RTC callouts into the ad request URL is determined by the Fast Fetch network implementation, and thus may vary. Please refer to the specific documentation for the Fast Fetch implementation in use, for instance refer to the DoubleClick RTC documentation if using DoubleClick for Fast Fetch.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eError Cases\u003c/h3\u003e\u003ca id=\"user-content-error-cases\" class=\"anchor\" aria-label=\"Permalink: Error Cases\" href=\"#error-cases\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eListed below are the most prominent error cases in RTC. For usage of the following error cases, see \u003ca href=\"https://github.com/ampproject/amphtml/blob/main/src/service/real-time-config/real-time-config-impl.js\"\u003ereal-time-config-impl.js\u003c/a\u003e\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch5 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eMisconfigured RTC Config\u003c/h5\u003e\u003ca id=\"user-content-misconfigured-rtc-config\" class=\"anchor\" aria-label=\"Permalink: Misconfigured RTC Config\" href=\"#misconfigured-rtc-config\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIf the RTC config specified by the publisher does not meet the specification defined in this document, an error will be logged to the console, and RTC will be aborted.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch5 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eBad JSON Response\u003c/h5\u003e\u003ca id=\"user-content-bad-json-response\" class=\"anchor\" aria-label=\"Permalink: Bad JSON Response\" href=\"#bad-json-response\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIf the response from an RTC callout is not valid JSON, i.e. JSON.parse fails, the response is dropped and ignored. An error is logged to the console.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch5 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eDuplicate Callout URLs\u003c/h5\u003e\u003ca id=\"user-content-duplicate-callout-urls\" class=\"anchor\" aria-label=\"Permalink: Duplicate Callout URLs\" href=\"#duplicate-callout-urls\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eRTC does not allow multiple callouts to identical URLs. Multiple callouts to the same domain are allowed, provided something in the path is different. I.e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThis is not allowed:\u003c/p\u003e\n\u003cmarkdown-accessiblity-table\u003e\u003ctable\u003e\n \u003ctbody\u003e\u003ctr\u003e\n \u003ctd\u003eCallout 1: `\u003ca href=\"https://www.vendor1.com/foo?slot_id=1234`\" rel=\"nofollow\"\u003ehttps://www.vendor1.com/foo?slot_id=1234`\u003c/a\u003e\n\u003cp dir=\"auto\"\u003e\nCallout 2: `\u003ca href=\"https://www.vendor1.com/foo?slot_id=1234`\" rel=\"nofollow\"\u003ehttps://www.vendor1.com/foo?slot_id=1234`\u003c/a\u003e\n \u003c/p\u003e\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd\u003eNot allowed\n \u003c/td\u003e\n \u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\u003c/markdown-accessiblity-table\u003e\n\u003cp dir=\"auto\"\u003eThis is allowed:\u003c/p\u003e\n\u003cmarkdown-accessiblity-table\u003e\u003ctable\u003e\n \u003ctbody\u003e\u003ctr\u003e\n \u003ctd\u003eCallout 1: `\u003ca href=\"https://www.vendor1.com/foo?slot_id=1234`\" rel=\"nofollow\"\u003ehttps://www.vendor1.com/foo?slot_id=1234`\u003c/a\u003e\n\u003cp dir=\"auto\"\u003e\nCallout 2: `\u003ca href=\"https://www.vendor1.com/foo?slot_id=5678`\" rel=\"nofollow\"\u003ehttps://www.vendor1.com/foo?slot_id=5678`\u003c/a\u003e\n \u003c/p\u003e\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n \u003ctd\u003eAllowed\n \u003c/td\u003e\n \u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\u003c/markdown-accessiblity-table\u003e\n\u003cp dir=\"auto\"\u003eIn the case that more than one callout is attempted to be sent to the same URL, only one will be sent, and an error will be logged to the console for each subsequent attempt to send a callout to that URL.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch5 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eInsecure URLs\u003c/h5\u003e\u003ca id=\"user-content-insecure-urls\" class=\"anchor\" aria-label=\"Permalink: Insecure URLs\" href=\"#insecure-urls\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAll RTC requests must be sent to valid SSL endpoints. An attempt to send a request to a URL that does not start with \u003ccode\u003ehttps://\u003c/code\u003e will be dropped. An error will be logged to the console.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch5 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eMaximum Callouts Exceeded\u003c/h5\u003e\u003ca id=\"user-content-maximum-callouts-exceeded\" class=\"anchor\" aria-label=\"Permalink: Maximum Callouts Exceeded\" href=\"#maximum-callouts-exceeded\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eRTC only allows a maximum of 5 RTC callouts to be sent per ad slot. Whether or not a valid response is received is irrelevant. If a request is dropped prior to actually being sent, it does not count against this limit. For instance, if a publisher specifies 7 URLs to send callouts to, and 2 of them get dropped due to being insecure URLs, then only 5 callouts will actually be sent. In the case that more than 5 callouts are attempted to be sent, only the first 5 will be, and all subsequent callouts will be ignored. An error will be logged to the console for each dropped callout.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eA publisher's custom URLs take precedence over vendor URLs, and are called out in the order in which they were specified. Then, the vendor URLs are called out, also in the order in which they were specified.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch5 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eNetwork Failure\u003c/h5\u003e\u003ca id=\"user-content-network-failure\" class=\"anchor\" aria-label=\"Permalink: Network Failure\" href=\"#network-failure\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIf the XHR GET fails somehow, for example, if network connectivity is lost, the request is lost and an error is logged to the console.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch5 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eUnknown Vendor\u003c/h5\u003e\u003ca id=\"user-content-unknown-vendor\" class=\"anchor\" aria-label=\"Permalink: Unknown Vendor\" href=\"#unknown-vendor\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIf a publisher specifies a vendor in their RTC-config that is not actually declared in callout-vendors.js, an error is logged to the console, and no request is sent.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch5 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eTimeout\u003c/h5\u003e\u003ca id=\"user-content-timeout\" class=\"anchor\" aria-label=\"Permalink: Timeout\" href=\"#timeout\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe timeout is either the default timeout of 1000ms, or a shorter timeout specified by the publisher in the RTC-config. If the time for a callout to complete exceeds the timeout, the request is dropped and an error is logged.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eSingle Request Architecture (SRA) Support\u003c/h3\u003e\u003ca id=\"user-content-single-request-architecture-sra-support\" class=\"anchor\" aria-label=\"Permalink: Single Request Architecture (SRA) Support\" href=\"#single-request-architecture-sra-support\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThere is no SRA support at this time. In the event that SRA and RTC are attempted to be used on the same page, RTC will take precedence, and SRA will not be used.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eEnd-to-End Example\u003c/h2\u003e\u003ca id=\"user-content-end-to-end-example\" class=\"anchor\" aria-label=\"Permalink: End-to-End Example\" href=\"#end-to-end-example\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAmpPublisher.biz uses FadNetwork's Fast Fetch implementation for all of their AMP pages. AmpPublisher.biz wants to start using RTC on their pages to add targeting information to their ad requests. They plan to make callouts to VendorA, VendorB, VendorC, and also to their own custom targeting servers: AmpPublisher.biz/A, and aptgt.biz/B.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eFirst, AmpPublisher's developer opens up callout-vendors.js to make sure that all of their desired vendors actually support RTC, and find:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-js notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"/** amp-a4a/0.1/callout-vendors.js */\nvendors: {\n \u0026quot;vendor-a\u0026quot;: {\n \u0026quot;url\u0026quot;: \u0026quot;https://vendora.com?slot_id=SLOT_ID\u0026amp;start_time=START\u0026quot;,\n \u0026quot;macros\u0026quot;: [\u0026quot;SLOT_ID\u0026quot;]\n },\n \u0026quot;vendor-b\u0026quot;: {\n \u0026quot;url\u0026quot;: \u0026quot;https://vendor-b.net/rtc?p_id=PAGE_ID\u0026amp;adw=AD_W\u0026quot;,\n \u0026quot;macros\u0026quot;: [\u0026quot;PAGE_ID\u0026quot;, \u0026quot;AD_W\u0026quot;]\n },\n \u0026quot;vendorc\u0026quot;: {\n \u0026quot;url\u0026quot;: \u0026quot;https://www.vendorC.co.uk/ept\u0026quot;\n }\n};\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e/** amp-a4a/0.1/callout-vendors.js */\u003c/span\u003e\nvendors: \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n \u003cspan class=\"pl-s\"\u003e\"vendor-a\"\u003c/span\u003e: \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n \u003cspan class=\"pl-s\"\u003e\"url\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\"https://vendora.com?slot_id=SLOT_ID\u0026amp;start_time=START\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n \u003cspan class=\"pl-s\"\u003e\"macros\"\u003c/span\u003e: \u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"SLOT_ID\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\n \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n \u003cspan class=\"pl-s\"\u003e\"vendor-b\"\u003c/span\u003e: \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n \u003cspan class=\"pl-s\"\u003e\"url\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\"https://vendor-b.net/rtc?p_id=PAGE_ID\u0026amp;adw=AD_W\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n \u003cspan class=\"pl-s\"\u003e\"macros\"\u003c/span\u003e: \u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"PAGE_ID\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"AD_W\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\n \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n \u003cspan class=\"pl-s\"\u003e\"vendorc\"\u003c/span\u003e: \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n \u003cspan class=\"pl-s\"\u003e\"url\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\"https://www.vendorC.co.uk/ept\"\u003c/span\u003e\n \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAll of the desired vendors are supported, thus they can use all of them.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eAmpPublisher now wants to check what macros they have available to use from FadNetwork's Fast Implementation, so they open up \u003cstrong\u003eamp-ad-network-fadnetwork-impl.js\u003c/strong\u003e and check the implementation of \u003cstrong\u003egetCustomRealTimeConfigMacros\u003c/strong\u003e:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-js notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"/** amp-ad-network-fadnetwork-impl.js */\n\nexport class AmpAdNetworkFadNetworkImpl extends AmpA4A {\n...\n/** @override */\ngetCustomRealTimeConfigMacros() {\n return {\n 'START': Date.now(),\n 'V_HT': getViewportHeight(),\n 'V_WT': getViewportWidth()\n }\n}\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e/** amp-ad-network-fadnetwork-impl.js */\u003c/span\u003e\n\n\u003cspan class=\"pl-k\"\u003eexport\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eAmpAdNetworkFadNetworkImpl\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eextends\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eAmpA4A\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n...\n\u003cspan class=\"pl-c\"\u003e/** \u003cspan class=\"pl-k\"\u003e@override\u003c/span\u003e */\u003c/span\u003e\n\u003cspan class=\"pl-en\"\u003egetCustomRealTimeConfigMacros\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n \u003cspan class=\"pl-s\"\u003e'START'\u003c/span\u003e: \u003cspan class=\"pl-v\"\u003eDate\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003enow\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n \u003cspan class=\"pl-s\"\u003e'V_HT'\u003c/span\u003e: \u003cspan class=\"pl-en\"\u003egetViewportHeight\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n \u003cspan class=\"pl-s\"\u003e'V_WT'\u003c/span\u003e: \u003cspan class=\"pl-en\"\u003egetViewportWidth\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\n \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThey see that FadNetwork supports the macros START, V_HT, and V_WT. AmpPublisher then decides that for their two targeting servers they want to call out to, only one of them could actually use these macros.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eAmpPublisher has also decided that the default timeout of 1000ms per callout is too slow for their purposes, and wants to shorten it to 750ms.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThus, they define their rtc-config:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-text-html-basic notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"\u0026lt;amp-ad\n width=\u0026quot;320\u0026quot;\n height=\u0026quot;50\u0026quot;\n type=\u0026quot;fadnetwork\u0026quot;\n data-slot=\u0026quot;/1234/5678\u0026quot;\n rtc-config='{\n \u0026quot;vendors\u0026quot;: {\n \u0026quot;vendor-a\u0026quot;: {\u0026quot;SLOT_ID\u0026quot;: \u0026quot;1\u0026quot;},\n \u0026quot;vendor-b\u0026quot;: {\u0026quot;PAGE_ID\u0026quot;: \u0026quot;61393\u0026quot;, \u0026quot;AD_W\u0026quot;: \u0026quot;320\u0026quot;},\n \u0026quot;vendorc\u0026quot;: {}\n },\n \u0026quot;urls\u0026quot;: [\n \u0026quot;https://www.AmpPublisher.biz/A\u0026quot;,\n \u0026quot;https://www.amptgt.biz/B?d=START\u0026amp;vht=V_HT\u0026amp;vwt=V_WT\u0026quot;\n ],\n \u0026quot;timeoutMillis\u0026quot;: 750\n }'\n\u0026gt;\n\u0026lt;/amp-ad\u0026gt;\"\u003e\u003cpre\u003e\u003cspan class=\"pl-kos\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003eamp-ad\u003c/span\u003e\n \u003cspan class=\"pl-c1\"\u003ewidth\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e320\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003eheight\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e50\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003etype\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003efadnetwork\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003edata-slot\u003c/span\u003e=\"\u003cspan class=\"pl-s\"\u003e/1234/5678\u003c/span\u003e\"\n \u003cspan class=\"pl-c1\"\u003ertc-config\u003c/span\u003e='\u003cspan class=\"pl-s\"\u003e{\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendors\": {\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendor-a\": {\"SLOT_ID\": \"1\"},\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendor-b\": {\"PAGE_ID\": \"61393\", \"AD_W\": \"320\"},\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"vendorc\": {}\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e },\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"urls\": [\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"https://www.AmpPublisher.biz/A\",\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"https://www.amptgt.biz/B?d=START\u0026amp;vht=V_HT\u0026amp;vwt=V_WT\"\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e ],\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e \"timeoutMillis\": 750\u003c/span\u003e\n\u003cspan class=\"pl-s\"\u003e }\u003c/span\u003e'\n\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"pl-ent\"\u003eamp-ad\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e\u0026gt;\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe setup of the HTML page is now done. At runtime, the next steps happen:\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eReal-time-config-manager parses the rtc-config from the ad slot, and uses macro substitution to construct the following 5 URLs:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-httpspec notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"https://vendora.com?slot_id=1\u0026amp;start_time=1508779857330\nhttps://vendor-b.net/rtc?p_id=61393\u0026amp;adw=320\nhttps://www.vendorC.co.uk/ept\nhttps://www.AmpPublisher.biz/A\nhttps://www.amptgt.biz/B?d=1508779857330\u0026amp;vht=1000\u0026amp;vwt=400\"\u003e\u003cpre\u003e\u003cspan class=\"pl-ii\"\u003ehttps://vendora.com?slot_id=1\u0026amp;start_time=1508779857330\u003c/span\u003e\n\u003cspan class=\"pl-ii\"\u003ehttps://vendor-b.net/rtc?p_id=61393\u0026amp;adw=320\u003c/span\u003e\n\u003cspan class=\"pl-ii\"\u003ehttps://www.vendorC.co.uk/ept\u003c/span\u003e\n\u003cspan class=\"pl-ii\"\u003ehttps://www.AmpPublisher.biz/A\u003c/span\u003e\n\u003cspan class=\"pl-ii\"\u003ehttps://www.amptgt.biz/B?d=1508779857330\u0026amp;vht=1000\u0026amp;vwt=400\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThese 5 URLs are then called out to as quickly as possible in parallel. A publisher's custom URLs take precedence over vendor URLs, so the actual order in which they send is:\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003ca target=\"_blank\" rel=\"noopener noreferrer\" href=\"/ampproject/amphtml/blob/main/extensions/amp-a4a/RTCDiagram.png\"\u003e\u003cimg src=\"/ampproject/amphtml/raw/main/extensions/amp-a4a/RTCDiagram.png\" alt=\"Image of RTC Callout Sequence Diagram\" style=\"max-width: 100%;\"\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe results of the 5 callouts are:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-js notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"/** Callout 1 response https://www.AmpPublisher.biz/A */\n{\u0026quot;targeting\u0026quot;: {\u0026quot;ages\u0026quot;: \u0026quot;18-24\u0026quot;, \u0026quot;g\u0026quot;:[\u0026quot;m\u0026quot;, \u0026quot;f\u0026quot;, \u0026quot;o\u0026quot;]}}\n\n/** Callout 2 response https://www.amptgt.biz/B?d=1508779857330\u0026amp;vht=1000\u0026amp;vwt=400 */\nNo Response, request was timed out due to surpassing 750ms.\n\n/** Callout 3 response VendorA */\n{\u0026quot;targeting\u0026quot;: {\u0026quot;vacation\u0026quot;: [\u0026quot;beach\u0026quot;, \u0026quot;city\u0026quot;]}}\n\n/** Callout 4 response VendorB */\n{\u0026quot;targeting\u0026quot;: {\u0026quot;ages\u0026quot;: \u0026quot;35-45\u0026quot;, \u0026quot;i\u0026quot;: {\u0026quot;sport\u0026quot;: \u0026quot;baseball\u0026quot;}}}\n\n/** Callout 5 response Vendor C */\n{\u0026quot;targeting\u0026quot;: {\u0026quot;i\u0026quot;: {\u0026quot;city\u0026quot;: \u0026quot;NYC\u0026quot;}}}\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e/** Callout 1 response https://www.AmpPublisher.biz/A */\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"targeting\"\u003c/span\u003e: \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"ages\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\"18-24\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"g\"\u003c/span\u003e:\u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"m\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"f\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"o\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e/** Callout 2 response https://www.amptgt.biz/B?d=1508779857330\u0026amp;vht=1000\u0026amp;vwt=400 */\u003c/span\u003e\n\u003cspan class=\"pl-v\"\u003eNo\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eResponse\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003erequest\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ewas\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003etimed\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eout\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003edue\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eto\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003esurpassing\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e750\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ems\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e/** Callout 3 response VendorA */\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"targeting\"\u003c/span\u003e: \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"vacation\"\u003c/span\u003e: \u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"beach\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"city\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e/** Callout 4 response VendorB */\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"targeting\"\u003c/span\u003e: \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"ages\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\"35-45\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\"i\"\u003c/span\u003e: \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"sport\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\"baseball\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e/** Callout 5 response Vendor C */\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"targeting\"\u003c/span\u003e: \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"i\"\u003c/span\u003e: \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\u003cspan class=\"pl-s\"\u003e\"city\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\"NYC\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAmpA4a builds a promise to an array of RTC Response Objects, and passes that Promise to \u003cstrong\u003egetAdUrl\u003c/strong\u003e in FadNetwork's Fast Fetch Implementation, which then resolves this promise.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-js notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"/** amp-ad-network-fadnetwork-impl.js */\n\nexport class AmpAdNetworkFadNetworkImpl extends AmpA4A {\n...\n\n /** @override */\n getAdUrl(opt_rtcResponsesPromise) {\n return opt_rtcResponsesPromise.then(rtcResponseArray =\u0026gt; {\n buildAndSendAdUrl(rtcResponseArray);\n });\n }\n}\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e/** amp-ad-network-fadnetwork-impl.js */\u003c/span\u003e\n\n\u003cspan class=\"pl-k\"\u003eexport\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eAmpAdNetworkFadNetworkImpl\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eextends\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eAmpA4A\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n...\n\n \u003cspan class=\"pl-c\"\u003e/** \u003cspan class=\"pl-k\"\u003e@override\u003c/span\u003e */\u003c/span\u003e\n \u003cspan class=\"pl-en\"\u003egetAdUrl\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003eopt_rtcResponsesPromise\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eopt_rtcResponsesPromise\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-en\"\u003ethen\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ertcResponseArray\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n \u003cspan class=\"pl-en\"\u003ebuildAndSendAdUrl\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1\"\u003ertcResponseArray\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\n \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIn this specific case, the Promise resolves to the following array:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-js notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"[\n /** Callout 1 RTC Response Object */\n {\n response: '{\u0026quot;targeting\u0026quot;: {\u0026quot;ages\u0026quot;: \u0026quot;18-24\u0026quot;, \u0026quot;g\u0026quot;:[\u0026quot;m\u0026quot;, \u0026quot;f\u0026quot;, \u0026quot;o\u0026quot;]}}',\n rtcTime: 685,\n callout: 'www.AmpPublisher.biz',\n },\n\n /** Callout 2 RTC Response Object */\n {error: 'timeout', rtcTime: 750, callout: 'www.amptgt.biz'},\n\n /** Callout 3 RTC Response Object */\n {error: 'malformed_json_response', rtcTime: 580, callout: 'vendora'},\n\n /** Callout 4 RTC Response Object */\n {\n response: '{\u0026quot;targeting\u0026quot;: {\u0026quot;ages\u0026quot;: \u0026quot;35-45\u0026quot;, \u0026quot;i\u0026quot;: {\u0026quot;sport\u0026quot;: \u0026quot;baseball\u0026quot;}}}',\n rtcTime: 700,\n callout: 'vendor-b',\n },\n\n /** Callout 5 RTC Response Object */\n {\n response: '{\u0026quot;targeting\u0026quot;: {\u0026quot;i\u0026quot;: {\u0026quot;city\u0026quot;: \u0026quot;NYC\u0026quot;}}}',\n rtcTime: 730,\n callout: 'vendorc',\n },\n];\"\u003e\u003cpre\u003e\u003cspan class=\"pl-kos\"\u003e[\u003c/span\u003e\n \u003cspan class=\"pl-c\"\u003e/** Callout 1 RTC Response Object */\u003c/span\u003e\n \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n \u003cspan class=\"pl-c1\"\u003eresponse\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e'{\"targeting\": {\"ages\": \"18-24\", \"g\":[\"m\", \"f\", \"o\"]}}'\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n \u003cspan class=\"pl-c1\"\u003ertcTime\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e685\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n \u003cspan class=\"pl-c1\"\u003ecallout\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e'www.AmpPublisher.biz'\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n\n \u003cspan class=\"pl-c\"\u003e/** Callout 2 RTC Response Object */\u003c/span\u003e\n \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eerror\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e'timeout'\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003ertcTime\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e750\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003ecallout\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e'www.amptgt.biz'\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n\n \u003cspan class=\"pl-c\"\u003e/** Callout 3 RTC Response Object */\u003c/span\u003e\n \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eerror\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e'malformed_json_response'\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003ertcTime\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e580\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003ecallout\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e'vendora'\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n\n \u003cspan class=\"pl-c\"\u003e/** Callout 4 RTC Response Object */\u003c/span\u003e\n \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n \u003cspan class=\"pl-c1\"\u003eresponse\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e'{\"targeting\": {\"ages\": \"35-45\", \"i\": {\"sport\": \"baseball\"}}}'\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n \u003cspan class=\"pl-c1\"\u003ertcTime\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e700\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n \u003cspan class=\"pl-c1\"\u003ecallout\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e'vendor-b'\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n\n \u003cspan class=\"pl-c\"\u003e/** Callout 5 RTC Response Object */\u003c/span\u003e\n \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n \u003cspan class=\"pl-c1\"\u003eresponse\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e'{\"targeting\": {\"i\": {\"city\": \"NYC\"}}}'\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n \u003cspan class=\"pl-c1\"\u003ertcTime\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e730\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n \u003cspan class=\"pl-c1\"\u003ecallout\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e'vendorc'\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e]\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e;\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eExample of Resolved Value of opt_rtcResponsesPromise passed to getAdUrl\u003c/strong\u003e\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003e_Explanation of Errors in RTC Responses _\u003c/strong\u003e\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cem\u003eCallout 2 surpassed the timeout of 750ms, so it gets dropped and an error is logged to the console.\u003c/em\u003e\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cem\u003eCallout 3 returns unparseable JSON, so it gets dropped and an error is logged.\u003c/em\u003e\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cem\u003eCallout 1, 4, and 5 all return valid JSON and cause no errors\u003c/em\u003e\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe Fast Fetch Implementation for FadNetwork then uses this array of RTC response objects to build and send the ad request URL. It is at the discretion of FadNetwork to merge these parameters however they see fit. In this example, FadNetwork simply does a deep merge of all the successful RTC callout responses, with the last response given precedence in case of collision, and gets the resulting JSON:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-json notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"{\n \u0026quot;targeting\u0026quot;: {\n \u0026quot;ages\u0026quot;: \u0026quot;35-45\u0026quot;,\n \u0026quot;g\u0026quot;: [\u0026quot;m\u0026quot;, \u0026quot;f\u0026quot;, \u0026quot;o\u0026quot;],\n \u0026quot;i\u0026quot;: {\u0026quot;sport\u0026quot;: \u0026quot;baseball\u0026quot;, \u0026quot;city\u0026quot;: \u0026quot;NYC\u0026quot;}\n }\n}\"\u003e\u003cpre\u003e{\n \u003cspan class=\"pl-ent\"\u003e\"targeting\"\u003c/span\u003e: {\n \u003cspan class=\"pl-ent\"\u003e\"ages\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e35-45\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e,\n \u003cspan class=\"pl-ent\"\u003e\"g\"\u003c/span\u003e: [\u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003em\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e, \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ef\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e, \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eo\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e],\n \u003cspan class=\"pl-ent\"\u003e\"i\"\u003c/span\u003e: {\u003cspan class=\"pl-ent\"\u003e\"sport\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003ebaseball\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e, \u003cspan class=\"pl-ent\"\u003e\"city\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003eNYC\u003cspan class=\"pl-pds\"\u003e\"\u003c/span\u003e\u003c/span\u003e}\n }\n}\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eResult of merging successful RTC Callouts 1, 4, and 5\u003c/strong\u003e\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eFadNetwork then constructs and encodes their Ad URL as:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-httpspec notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"https://www.fadnetwork.biz/adServer?%7B%E2%80%9Ctargeting%E2%80%9D:%20%7B%E2%80%9Cages%E2%80%9D:%20%E2%80%9C35-45%E2%80%9D,%20%E2%80%9Cg%E2%80%9D:%5B%E2%80%9Cm%E2%80%9D,%20%E2%80%9Cf%E2%80%9D,%20%E2%80%9Co%E2%80%9D%5D,%20%E2%80%9Ci%E2%80%9D:%20%7B%E2%80%9Csport%E2%80%9D:%20%E2%80%9Cbaseball%E2%80%9D,%20%E2%80%9Ccity%E2%80%9D:%20%E2%80%9CNYC%E2%80%9D%7D%7D\"\u003e\u003cpre\u003e\u003cspan class=\"pl-ii\"\u003ehttps://www.fadnetwork.biz/adServer?%7B%E2%80%9Ctargeting%E2%80%9D:%20%7B%E2%80%9Cages%E2%80%9D:%20%E2%80%9C35-45%E2%80%9D,%20%E2%80%9Cg%E2%80%9D:%5B%E2%80%9Cm%E2%80%9D,%20%E2%80%9Cf%E2%80%9D,%20%E2%80%9Co%E2%80%9D%5D,%20%E2%80%9Ci%E2%80%9D:%20%7B%E2%80%9Csport%E2%80%9D:%20%E2%80%9Cbaseball%E2%80%9D,%20%E2%80%9Ccity%E2%80%9D:%20%E2%80%9CNYC%E2%80%9D%7D%7D\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eFadNetwork's resulting Ad Request URL (use decodeURI to see original json)\u003c/strong\u003e\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eFrom this point forward, all Fast Fetch behavior is exactly the same as non-RTC use cases, and regular Fast Fetch documentation may be consulted for additional questions.\u003c/p\u003e\n\u003c/article\u003e","renderedFileInfo":null,"shortPath":null,"symbolsEnabled":true,"tabSize":2,"topBannersInfo":{"overridingGlobalFundingFile":false,"globalPreferredFundingPath":null,"showInvalidCitationWarning":false,"citationHelpUrl":"https://docs.github.com/github/creating-cloning-and-archiving-repositories/creating-a-repository-on-github/about-citation-files","actionsOnboardingTip":null},"truncated":false,"viewable":true,"workflowRedirectUrl":null,"symbols":{"timed_out":false,"not_analyzed":false,"symbols":[{"name":"AMP Real Time Config","kind":"section_1","ident_start":2,"ident_end":22,"extent_start":0,"extent_end":38688,"fully_qualified_name":"AMP Real Time Config","ident_utf16":{"start":{"line_number":0,"utf16_col":2},"end":{"line_number":0,"utf16_col":22}},"extent_utf16":{"start":{"line_number":0,"utf16_col":0},"end":{"line_number":861,"utf16_col":0}}},{"name":"Objective","kind":"section_2","ident_start":27,"ident_end":36,"extent_start":24,"extent_end":190,"fully_qualified_name":"Objective","ident_utf16":{"start":{"line_number":2,"utf16_col":3},"end":{"line_number":2,"utf16_col":12}},"extent_utf16":{"start":{"line_number":2,"utf16_col":0},"end":{"line_number":6,"utf16_col":0}}},{"name":"Background","kind":"section_2","ident_start":193,"ident_end":203,"extent_start":190,"extent_end":1179,"fully_qualified_name":"Background","ident_utf16":{"start":{"line_number":6,"utf16_col":3},"end":{"line_number":6,"utf16_col":13}},"extent_utf16":{"start":{"line_number":6,"utf16_col":0},"end":{"line_number":10,"utf16_col":0}}},{"name":"Overview","kind":"section_2","ident_start":1182,"ident_end":1190,"extent_start":1179,"extent_end":3038,"fully_qualified_name":"Overview","ident_utf16":{"start":{"line_number":10,"utf16_col":3},"end":{"line_number":10,"utf16_col":11}},"extent_utf16":{"start":{"line_number":10,"utf16_col":0},"end":{"line_number":24,"utf16_col":0}}},{"name":"Custom URL callout","kind":"section_3","ident_start":1468,"ident_end":1486,"extent_start":1464,"extent_end":1831,"fully_qualified_name":"Custom URL callout","ident_utf16":{"start":{"line_number":14,"utf16_col":4},"end":{"line_number":14,"utf16_col":22}},"extent_utf16":{"start":{"line_number":14,"utf16_col":0},"end":{"line_number":18,"utf16_col":0}}},{"name":"Vendor-specified URL Callout","kind":"section_3","ident_start":1835,"ident_end":1863,"extent_start":1831,"extent_end":3038,"fully_qualified_name":"Vendor-specified URL Callout","ident_utf16":{"start":{"line_number":18,"utf16_col":4},"end":{"line_number":18,"utf16_col":32}},"extent_utf16":{"start":{"line_number":18,"utf16_col":0},"end":{"line_number":24,"utf16_col":0}}},{"name":"Design","kind":"section_2","ident_start":3041,"ident_end":3047,"extent_start":3038,"extent_end":32182,"fully_qualified_name":"Design","ident_utf16":{"start":{"line_number":24,"utf16_col":3},"end":{"line_number":24,"utf16_col":9}},"extent_utf16":{"start":{"line_number":24,"utf16_col":0},"end":{"line_number":673,"utf16_col":0}}},{"name":"Per-Slot RTC Specification","kind":"section_3","ident_start":3053,"ident_end":3079,"extent_start":3049,"extent_end":6767,"fully_qualified_name":"Per-Slot RTC Specification","ident_utf16":{"start":{"line_number":26,"utf16_col":4},"end":{"line_number":26,"utf16_col":30}},"extent_utf16":{"start":{"line_number":26,"utf16_col":0},"end":{"line_number":100,"utf16_col":0}}},{"name":"Example 1: RTC specification on an amp-ad","kind":"section_4","ident_start":3260,"ident_end":3301,"extent_start":3255,"extent_end":6767,"fully_qualified_name":"Example 1: RTC specification on an amp-ad","ident_utf16":{"start":{"line_number":30,"utf16_col":5},"end":{"line_number":30,"utf16_col":46}},"extent_utf16":{"start":{"line_number":30,"utf16_col":0},"end":{"line_number":100,"utf16_col":0}}},{"name":"Vendor URL Specification","kind":"section_3","ident_start":6771,"ident_end":6795,"extent_start":6767,"extent_end":9127,"fully_qualified_name":"Vendor URL Specification","ident_utf16":{"start":{"line_number":100,"utf16_col":4},"end":{"line_number":100,"utf16_col":28}},"extent_utf16":{"start":{"line_number":100,"utf16_col":0},"end":{"line_number":164,"utf16_col":0}}},{"name":"Currently Supported Vendors","kind":"section_4","ident_start":8504,"ident_end":8531,"extent_start":8499,"extent_end":9127,"fully_qualified_name":"Currently Supported Vendors","ident_utf16":{"start":{"line_number":123,"utf16_col":5},"end":{"line_number":123,"utf16_col":32}},"extent_utf16":{"start":{"line_number":123,"utf16_col":0},"end":{"line_number":164,"utf16_col":0}}},{"name":"RTC Callout Request Specification","kind":"section_3","ident_start":9131,"ident_end":9164,"extent_start":9127,"extent_end":9739,"fully_qualified_name":"RTC Callout Request Specification","ident_utf16":{"start":{"line_number":164,"utf16_col":4},"end":{"line_number":164,"utf16_col":37}},"extent_utf16":{"start":{"line_number":164,"utf16_col":0},"end":{"line_number":179,"utf16_col":0}}},{"name":"RTC Callout Endpoint and Response Specification","kind":"section_3","ident_start":9743,"ident_end":9790,"extent_start":9739,"extent_end":11216,"fully_qualified_name":"RTC Callout Endpoint and Response Specification","ident_utf16":{"start":{"line_number":179,"utf16_col":4},"end":{"line_number":179,"utf16_col":51}},"extent_utf16":{"start":{"line_number":179,"utf16_col":0},"end":{"line_number":195,"utf16_col":0}}},{"name":"RTC Error Pingback","kind":"section_3","ident_start":11220,"ident_end":11238,"extent_start":11216,"extent_end":13635,"fully_qualified_name":"RTC Error Pingback","ident_utf16":{"start":{"line_number":195,"utf16_col":4},"end":{"line_number":195,"utf16_col":22}},"extent_utf16":{"start":{"line_number":195,"utf16_col":0},"end":{"line_number":244,"utf16_col":0}}},{"name":"AMP Consent Integration","kind":"section_3","ident_start":13639,"ident_end":13662,"extent_start":13635,"extent_end":21903,"fully_qualified_name":"AMP Consent Integration","ident_utf16":{"start":{"line_number":244,"utf16_col":4},"end":{"line_number":244,"utf16_col":27}},"extent_utf16":{"start":{"line_number":244,"utf16_col":0},"end":{"line_number":410,"utf16_col":0}}},{"name":"Allow all RTC callouts for all consent states","kind":"section_4","ident_start":15735,"ident_end":15780,"extent_start":15730,"extent_end":16471,"fully_qualified_name":"Allow all RTC callouts for all consent states","ident_utf16":{"start":{"line_number":256,"utf16_col":5},"end":{"line_number":256,"utf16_col":50}},"extent_utf16":{"start":{"line_number":256,"utf16_col":0},"end":{"line_number":281,"utf16_col":0}}},{"name":"Allow all RTC callouts for only certain consent states","kind":"section_4","ident_start":16476,"ident_end":16530,"extent_start":16471,"extent_end":17533,"fully_qualified_name":"Allow all RTC callouts for only certain consent states","ident_utf16":{"start":{"line_number":281,"utf16_col":5},"end":{"line_number":281,"utf16_col":59}},"extent_utf16":{"start":{"line_number":281,"utf16_col":0},"end":{"line_number":306,"utf16_col":0}}},{"name":"Allow some RTC callouts in the \"url\" array","kind":"section_4","ident_start":17538,"ident_end":17580,"extent_start":17533,"extent_end":19022,"fully_qualified_name":"Allow some RTC callouts in the \"url\" array","ident_utf16":{"start":{"line_number":306,"utf16_col":5},"end":{"line_number":306,"utf16_col":47}},"extent_utf16":{"start":{"line_number":306,"utf16_col":0},"end":{"line_number":354,"utf16_col":0}}},{"name":"Allow some RTC callouts in the \"vendors\" object","kind":"section_4","ident_start":19027,"ident_end":19074,"extent_start":19022,"extent_end":19869,"fully_qualified_name":"Allow some RTC callouts in the \"vendors\" object","ident_utf16":{"start":{"line_number":354,"utf16_col":5},"end":{"line_number":354,"utf16_col":52}},"extent_utf16":{"start":{"line_number":354,"utf16_col":0},"end":{"line_number":379,"utf16_col":0}}},{"name":"Mixture of settings","kind":"section_4","ident_start":19874,"ident_end":19893,"extent_start":19869,"extent_end":21903,"fully_qualified_name":"Mixture of settings","ident_utf16":{"start":{"line_number":379,"utf16_col":5},"end":{"line_number":379,"utf16_col":24}},"extent_utf16":{"start":{"line_number":379,"utf16_col":0},"end":{"line_number":410,"utf16_col":0}}},{"name":"Blocking RTC","kind":"section_3","ident_start":21907,"ident_end":21919,"extent_start":21903,"extent_end":23146,"fully_qualified_name":"Blocking RTC","ident_utf16":{"start":{"line_number":410,"utf16_col":4},"end":{"line_number":410,"utf16_col":16}},"extent_utf16":{"start":{"line_number":410,"utf16_col":0},"end":{"line_number":447,"utf16_col":0}}},{"name":"URL Macro Substitution","kind":"section_3","ident_start":23150,"ident_end":23172,"extent_start":23146,"extent_end":28528,"fully_qualified_name":"URL Macro Substitution","ident_utf16":{"start":{"line_number":447,"utf16_col":4},"end":{"line_number":447,"utf16_col":26}},"extent_utf16":{"start":{"line_number":447,"utf16_col":0},"end":{"line_number":595,"utf16_col":0}}},{"name":"Vendor Defined Macros","kind":"section_4","ident_start":23316,"ident_end":23337,"extent_start":23311,"extent_end":24262,"fully_qualified_name":"Vendor Defined Macros","ident_utf16":{"start":{"line_number":451,"utf16_col":5},"end":{"line_number":451,"utf16_col":26}},"extent_utf16":{"start":{"line_number":451,"utf16_col":0},"end":{"line_number":490,"utf16_col":0}}},{"name":"Example 2: Use of Vendor URLs","kind":"section_5","ident_start":23804,"ident_end":23833,"extent_start":23798,"extent_end":24262,"fully_qualified_name":"Example 2: Use of Vendor URLs","ident_utf16":{"start":{"line_number":467,"utf16_col":6},"end":{"line_number":467,"utf16_col":35}},"extent_utf16":{"start":{"line_number":467,"utf16_col":0},"end":{"line_number":490,"utf16_col":0}}},{"name":"Fast Fetch Implementation Defined Macros","kind":"section_4","ident_start":24267,"ident_end":24307,"extent_start":24262,"extent_end":28528,"fully_qualified_name":"Fast Fetch Implementation Defined Macros","ident_utf16":{"start":{"line_number":490,"utf16_col":5},"end":{"line_number":490,"utf16_col":45}},"extent_utf16":{"start":{"line_number":490,"utf16_col":0},"end":{"line_number":595,"utf16_col":0}}},{"name":"Example 3: Fast Fetch implementation defined macros","kind":"section_5","ident_start":25020,"ident_end":25071,"extent_start":25014,"extent_end":25638,"fully_qualified_name":"Example 3: Fast Fetch implementation defined macros","ident_utf16":{"start":{"line_number":494,"utf16_col":6},"end":{"line_number":494,"utf16_col":57}},"extent_utf16":{"start":{"line_number":494,"utf16_col":0},"end":{"line_number":514,"utf16_col":0}}},{"name":"Vendor Macro Substitution with Fast Fetch Network Macro Substitution","kind":"section_5","ident_start":25644,"ident_end":25712,"extent_start":25638,"extent_end":27656,"fully_qualified_name":"Vendor Macro Substitution with Fast Fetch Network Macro Substitution","ident_utf16":{"start":{"line_number":514,"utf16_col":6},"end":{"line_number":514,"utf16_col":74}},"extent_utf16":{"start":{"line_number":514,"utf16_col":0},"end":{"line_number":571,"utf16_col":0}}},{"name":"Example 4","kind":"section_6","ident_start":25963,"ident_end":25972,"extent_start":25956,"extent_end":27656,"fully_qualified_name":"Example 4","ident_utf16":{"start":{"line_number":518,"utf16_col":7},"end":{"line_number":518,"utf16_col":16}},"extent_utf16":{"start":{"line_number":518,"utf16_col":0},"end":{"line_number":571,"utf16_col":0}}},{"name":"Conflicting macro substitution","kind":"section_5","ident_start":27662,"ident_end":27692,"extent_start":27656,"extent_end":28528,"fully_qualified_name":"Conflicting macro substitution","ident_utf16":{"start":{"line_number":571,"utf16_col":6},"end":{"line_number":571,"utf16_col":36}},"extent_utf16":{"start":{"line_number":571,"utf16_col":0},"end":{"line_number":595,"utf16_col":0}}},{"name":"RTC Callout Result Merging","kind":"section_3","ident_start":28532,"ident_end":28558,"extent_start":28528,"extent_end":28885,"fully_qualified_name":"RTC Callout Result Merging","ident_utf16":{"start":{"line_number":595,"utf16_col":4},"end":{"line_number":595,"utf16_col":30}},"extent_utf16":{"start":{"line_number":595,"utf16_col":0},"end":{"line_number":599,"utf16_col":0}}},{"name":"Error Cases","kind":"section_3","ident_start":28889,"ident_end":28900,"extent_start":28885,"extent_end":31971,"fully_qualified_name":"Error Cases","ident_utf16":{"start":{"line_number":599,"utf16_col":4},"end":{"line_number":599,"utf16_col":15}},"extent_utf16":{"start":{"line_number":599,"utf16_col":0},"end":{"line_number":669,"utf16_col":0}}},{"name":"Misconfigured RTC Config","kind":"section_5","ident_start":29139,"ident_end":29163,"extent_start":29133,"extent_end":29334,"fully_qualified_name":"Misconfigured RTC Config","ident_utf16":{"start":{"line_number":603,"utf16_col":6},"end":{"line_number":603,"utf16_col":30}},"extent_utf16":{"start":{"line_number":603,"utf16_col":0},"end":{"line_number":607,"utf16_col":0}}},{"name":"Bad JSON Response","kind":"section_5","ident_start":29340,"ident_end":29357,"extent_start":29334,"extent_end":29510,"fully_qualified_name":"Bad JSON Response","ident_utf16":{"start":{"line_number":607,"utf16_col":6},"end":{"line_number":607,"utf16_col":23}},"extent_utf16":{"start":{"line_number":607,"utf16_col":0},"end":{"line_number":611,"utf16_col":0}}},{"name":"Duplicate Callout URLs","kind":"section_5","ident_start":29516,"ident_end":29538,"extent_start":29510,"extent_end":30347,"fully_qualified_name":"Duplicate Callout URLs","ident_utf16":{"start":{"line_number":611,"utf16_col":6},"end":{"line_number":611,"utf16_col":28}},"extent_utf16":{"start":{"line_number":611,"utf16_col":0},"end":{"line_number":647,"utf16_col":0}}},{"name":"Insecure URLs","kind":"section_5","ident_start":30353,"ident_end":30366,"extent_start":30347,"extent_end":30554,"fully_qualified_name":"Insecure URLs","ident_utf16":{"start":{"line_number":647,"utf16_col":6},"end":{"line_number":647,"utf16_col":19}},"extent_utf16":{"start":{"line_number":647,"utf16_col":0},"end":{"line_number":651,"utf16_col":0}}},{"name":"Maximum Callouts Exceeded","kind":"section_5","ident_start":30560,"ident_end":30585,"extent_start":30554,"extent_end":31381,"fully_qualified_name":"Maximum Callouts Exceeded","ident_utf16":{"start":{"line_number":651,"utf16_col":6},"end":{"line_number":651,"utf16_col":31}},"extent_utf16":{"start":{"line_number":651,"utf16_col":0},"end":{"line_number":657,"utf16_col":0}}},{"name":"Network Failure","kind":"section_5","ident_start":31387,"ident_end":31402,"extent_start":31381,"extent_end":31540,"fully_qualified_name":"Network Failure","ident_utf16":{"start":{"line_number":657,"utf16_col":6},"end":{"line_number":657,"utf16_col":21}},"extent_utf16":{"start":{"line_number":657,"utf16_col":0},"end":{"line_number":661,"utf16_col":0}}},{"name":"Unknown Vendor","kind":"section_5","ident_start":31546,"ident_end":31560,"extent_start":31540,"extent_end":31729,"fully_qualified_name":"Unknown Vendor","ident_utf16":{"start":{"line_number":661,"utf16_col":6},"end":{"line_number":661,"utf16_col":20}},"extent_utf16":{"start":{"line_number":661,"utf16_col":0},"end":{"line_number":665,"utf16_col":0}}},{"name":"Timeout","kind":"section_5","ident_start":31735,"ident_end":31742,"extent_start":31729,"extent_end":31971,"fully_qualified_name":"Timeout","ident_utf16":{"start":{"line_number":665,"utf16_col":6},"end":{"line_number":665,"utf16_col":13}},"extent_utf16":{"start":{"line_number":665,"utf16_col":0},"end":{"line_number":669,"utf16_col":0}}},{"name":"Single Request Architecture (SRA) Support","kind":"section_3","ident_start":31975,"ident_end":32016,"extent_start":31971,"extent_end":32182,"fully_qualified_name":"Single Request Architecture (SRA) Support","ident_utf16":{"start":{"line_number":669,"utf16_col":4},"end":{"line_number":669,"utf16_col":45}},"extent_utf16":{"start":{"line_number":669,"utf16_col":0},"end":{"line_number":673,"utf16_col":0}}},{"name":"End-to-End Example","kind":"section_2","ident_start":32185,"ident_end":32203,"extent_start":32182,"extent_end":38688,"fully_qualified_name":"End-to-End Example","ident_utf16":{"start":{"line_number":673,"utf16_col":3},"end":{"line_number":673,"utf16_col":21}},"extent_utf16":{"start":{"line_number":673,"utf16_col":0},"end":{"line_number":861,"utf16_col":0}}}]}},"copilotInfo":null,"copilotAccessAllowed":false,"modelsAccessAllowed":false,"csrf_tokens":{"/ampproject/amphtml/branches":{"post":"ZMvydZ_ds7uq_stwU3tMH94l-0kniv0QYI6dQGHG8IKB39EbjPXQHJBN3CQKVwwRG_trYCWqh7Dxet3Fjr-1fA"},"/repos/preferences":{"post":"28owEgJz2xBDVD5COji36U-wjxb0a5xQ91Ndg5oj_zxLM0bUvTlZTsKB7BgUYvQomgr7lns5mN5hlGsw_VApZA"}}},"title":"amphtml/extensions/amp-a4a/rtc-documentation.md at main · ampproject/amphtml","appPayload":{"helpUrl":"https://docs.github.com","findFileWorkerPath":"/assets-cdn/worker/find-file-worker-9f8a877aa99f.js","findInFileWorkerPath":"/assets-cdn/worker/find-in-file-worker-96e76d5fdb2c.js","githubDevUrl":null,"enabled_features":{"code_nav_ui_events":false,"overview_shared_code_dropdown_button":false,"react_blob_overlay":false,"copilot_conversational_ux_embedding_update":false,"copilot_smell_icebreaker_ux":true,"accessible_code_button":true}}}</script> <div data-target="react-app.reactRoot"><style data-styled="true" data-styled-version="5.3.11">.hOfjFo{padding:0;}/*!sc*/ .oDGAe{max-width:100%;margin-left:auto;margin-right:auto;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;}/*!sc*/ .kowOcT{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:1 1 100%;-ms-flex:1 1 100%;flex:1 1 100%;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;max-width:100%;}/*!sc*/ .gISSDQ{width:100%;}/*!sc*/ @media screen and (min-width:544px){.gISSDQ{width:100%;}}/*!sc*/ @media screen and (min-width:768px){.gISSDQ{width:auto;}}/*!sc*/ .cEmWSE{display:none;-webkit-order:1;-ms-flex-order:1;order:1;width:100%;margin-left:0;margin-right:0;-webkit-flex-direction:column-reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse;margin-bottom:0;min-width:0;}/*!sc*/ @media screen and (min-width:768px){.cEmWSE{width:auto;margin-top:0 !important;margin-bottom:0 !important;position:-webkit-sticky;position:sticky;top:0px;max-height:100vh !important;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;margin-right:0;height:100vh;}}/*!sc*/ @media print,screen and (max-width:1011px) and (min-width:768px){.cEmWSE{display:none;}}/*!sc*/ .hPvFuC{margin-left:0;margin-right:0;display:none;margin-top:0;}/*!sc*/ @media screen and (min-width:768px){.hPvFuC{margin-left:0 !important;margin-right:0 !important;}}/*!sc*/ .fFSoPl{--pane-min-width:256px;--pane-max-width-diff:511px;--pane-max-width:calc(100vw - var(--pane-max-width-diff));width:100%;padding:0;}/*!sc*/ @media screen and (min-width:544px){}/*!sc*/ @media screen and (min-width:768px){.fFSoPl{width:clamp(var(--pane-min-width),var(--pane-width),var(--pane-max-width));overflow:auto;}}/*!sc*/ @media screen and (min-width:1280px){.fFSoPl{--pane-max-width-diff:959px;}}/*!sc*/ .bTBnTW{height:100%;position:relative;display:none;margin-left:0;}/*!sc*/ .bHLmSv{position:absolute;inset:0 -2px;cursor:col-resize;background-color:transparent;-webkit-transition-delay:0.1s;transition-delay:0.1s;}/*!sc*/ .bHLmSv:hover{background-color:var(--bgColor-neutral-muted,var(--color-neutral-muted,rgba(175,184,193,0.2)));}/*!sc*/ .iKqMNA{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-order:2;-ms-flex-order:2;order:2;-webkit-flex-basis:0;-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;-webkit-flex-shrink:1;-ms-flex-negative:1;flex-shrink:1;min-width:1px;margin-right:auto;}/*!sc*/ @media print{.iKqMNA{display:-webkit-box !important;display:-webkit-flex !important;display:-ms-flexbox !important;display:flex !important;}}/*!sc*/ .FxAyp{width:100%;max-width:100%;margin-left:auto;margin-right:auto;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;padding:0;}/*!sc*/ .leYMvG{margin-left:auto;margin-right:auto;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding-bottom:40px;max-width:100%;margin-top:0;}/*!sc*/ .KMPzq{display:inherit;}/*!sc*/ .hfKjHv{width:100%;}/*!sc*/ .gZWyZE{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;gap:8px;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;width:100%;}/*!sc*/ .dwYKDk{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:start;-webkit-box-align:start;-ms-flex-align:start;align-items:start;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;gap:8px;}/*!sc*/ .ibcGmb{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:start;-webkit-box-align:start;-ms-flex-align:start;align-items:start;min-width:0;}/*!sc*/ .hKaEJF{display:block;margin-right:8px;}/*!sc*/ @media screen and (min-width:1360px){.hKaEJF{display:block;}}/*!sc*/ .XosP{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;font-size:14px;}/*!sc*/ .bCKfWo[data-size="medium"]{color:var(--fgColor-muted,var(--color-fg-muted,#656d76));padding-left:8px;padding-right:8px;display:none;}/*!sc*/ @media screen and (max-width:768px){.bCKfWo[data-size="medium"]{display:block;}}/*!sc*/ .gUkoLg{-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;}/*!sc*/ .dmxRgG[data-size="medium"]{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}/*!sc*/ .dmxRgG[data-size="medium"] svg{color:var(--fgColor-muted,var(--color-fg-muted,#656d76));}/*!sc*/ .dmxRgG[data-size="medium"] > span{width:inherit;}/*!sc*/ .bZBlpz{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;width:100%;}/*!sc*/ .lhTYNA{margin-right:4px;color:var(--fgColor-muted,var(--color-fg-muted,#656d76));}/*!sc*/ .dbrgmi{font-size:14px;min-width:0;max-width:125px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}/*!sc*/ .dHJiml{-webkit-align-self:center;-ms-flex-item-align:center;align-self:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;padding-left:8px;padding-right:8px;min-width:0;}/*!sc*/ .cEytCf{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;font-size:16px;min-width:0;-webkit-flex-shrink:1;-ms-flex-negative:1;flex-shrink:1;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;max-width:100%;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}/*!sc*/ .fzFXnm{max-width:100%;}/*!sc*/ .iMnkmv{max-width:100%;list-style:none;display:inline-block;}/*!sc*/ .ghzDag{display:inline-block;max-width:100%;}/*!sc*/ .kHuKdh{font-weight:600;}/*!sc*/ .kgiVEz{font-weight:400;}/*!sc*/ .jGhzSQ{font-weight:600;display:inline-block;max-width:100%;font-size:16px;}/*!sc*/ .faNtbn{min-height:32px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:start;-webkit-box-align:start;-ms-flex-align:start;align-items:start;}/*!sc*/ .fmQaBv{margin-left:4px;margin-right:4px;}/*!sc*/ .dwNhzn[data-size="medium"][data-no-visuals]{border-top-left-radius:0;border-bottom-left-radius:0;display:none;}/*!sc*/ .fGwBZA[data-size="medium"][data-no-visuals]{color:var(--fgColor-muted,var(--color-fg-muted,#656d76));}/*!sc*/ .dJxjrT{margin-left:16px;margin-right:16px;}/*!sc*/ .eFxKDQ{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}/*!sc*/ .dzCJzi{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:8px;min-width:273px;padding:8px;}/*!sc*/ @media screen and (min-width:544px){.dzCJzi{-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;}}/*!sc*/ .ldRxiI{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;}/*!sc*/ .fVkfyA{width:100%;height:-webkit-fit-content;height:-moz-fit-content;height:fit-content;min-width:0;margin-right:0;}/*!sc*/ .gNAmSV{height:40px;padding-left:4px;padding-bottom:16px;}/*!sc*/ .jNEwzY{-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}/*!sc*/ .bsDwxw{font-size:12px;-webkit-flex:auto;-ms-flex:auto;flex:auto;padding-right:16px;color:var(--fgColor-muted,var(--color-fg-muted,#656d76));min-width:0;}/*!sc*/ .jdLMhu{top:0px;z-index:4;background:var(--bgColor-default,var(--color-canvas-default));position:-webkit-sticky;position:sticky;}/*!sc*/ .tOISc{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;width:100%;position:absolute;}/*!sc*/ .hqwSEx{display:none;min-width:0;padding-top:8px;padding-bottom:8px;}/*!sc*/ .bDVoEr{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;overflow:hidden;margin-left:8px;margin-right:8px;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;width:100%;}/*!sc*/ .kYLlPM{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}/*!sc*/ .gYjEmn{margin-left:4px;margin-right:8px;}/*!sc*/ .kGqOLL{text-overflow:ellipsis;overflow:hidden;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}/*!sc*/ .fHind{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;font-size:14px;min-width:0;-webkit-flex-shrink:1;-ms-flex-negative:1;flex-shrink:1;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;max-width:100%;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}/*!sc*/ .dnZoUW{font-weight:600;display:inline-block;max-width:100%;font-size:14px;}/*!sc*/ .jRZWlf[data-size="small"]{color:var(--fgColor-default,var(--color-fg-default,#1F2328));margin-left:8px;}/*!sc*/ .kTvpNk{padding-left:8px;padding-top:8px;padding-bottom:8px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:1;-ms-flex:1;flex:1;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;background-color:var(--bgColor-muted,var(--color-canvas-subtle,#f6f8fa));border:1px solid var(--borderColor-default,var(--color-border-default));border-radius:6px 6px 0px 0px;}/*!sc*/ .iNMjfP{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:8px;min-width:0;}/*!sc*/ .fefCSX{display:block;position:relative;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;margin-top:-1px;margin-bottom:-1px;--separator-color:transparent;}/*!sc*/ .fefCSX:not(:last-child){margin-right:1px;}/*!sc*/ .fefCSX:not(:last-child):after{background-color:var(--separator-color);content:"";position:absolute;right:-2px;top:8px;bottom:8px;width:1px;}/*!sc*/ .fefCSX:focus-within:has(:focus-visible){--separator-color:transparent;}/*!sc*/ .fefCSX:first-child{margin-left:-1px;}/*!sc*/ .fefCSX:last-child{margin-right:-1px;}/*!sc*/ .idgUkN{display:block;position:relative;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;margin-top:-1px;margin-bottom:-1px;--separator-color:var(--borderColor-default,var(--color-border-default,#d0d7de));}/*!sc*/ .idgUkN:not(:last-child){margin-right:1px;}/*!sc*/ .idgUkN:not(:last-child):after{background-color:var(--separator-color);content:"";position:absolute;right:-2px;top:8px;bottom:8px;width:1px;}/*!sc*/ .idgUkN:focus-within:has(:focus-visible){--separator-color:transparent;}/*!sc*/ .idgUkN:first-child{margin-left:-1px;}/*!sc*/ .idgUkN:last-child{margin-right:-1px;}/*!sc*/ .kcLCKF{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:8px;margin-right:8px;}/*!sc*/ .kVWtTz{gap:8px;}/*!sc*/ .gWqxTd{padding-left:8px;padding-right:8px;}/*!sc*/ .gWqxTd linkButtonSx:hover:not([disabled]){-webkit-text-decoration:none;text-decoration:none;}/*!sc*/ .gWqxTd linkButtonSx:focus:not([disabled]){-webkit-text-decoration:none;text-decoration:none;}/*!sc*/ .gWqxTd linkButtonSx:active:not([disabled]){-webkit-text-decoration:none;text-decoration:none;}/*!sc*/ .ivobqY[data-size="small"][data-no-visuals]{border-top-left-radius:0;border-bottom-left-radius:0;}/*!sc*/ .iNRSob[data-size="small"][data-no-visuals]{color:var(--fgColor-muted,var(--color-fg-muted));margin-right:8px;}/*!sc*/ .ffkqe[data-size="small"][data-no-visuals]{color:var(--fgColor-muted,var(--color-fg-muted,#656d76));}/*!sc*/ .hGyMdv{border:1px solid;border-top:none;border-color:var(--borderColor-default,var(--color-border-default,#d0d7de));border-radius:0px 0px 6px 6px;min-width:273px;}/*!sc*/ .fGqKFv{background-color:var(--bgColor-default,var(--color-canvas-default));border:0px;border-width:0;border-radius:0px 0px 6px 6px;padding:0;min-width:0;margin-top:46px;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;}/*!sc*/ .eoaCFS{border-bottom-left-radius:6px;border-bottom-right-radius:6px;padding:32px;min-width:0;}/*!sc*/ .cCoXib{position:fixed;top:0;right:0;height:100%;width:15px;-webkit-transition:-webkit-transform 0.3s;-webkit-transition:transform 0.3s;transition:transform 0.3s;z-index:1;}/*!sc*/ .cCoXib:hover{-webkit-transform:scaleX(1.5);-ms-transform:scaleX(1.5);transform:scaleX(1.5);}/*!sc*/ data-styled.g1[id="Box-sc-g0xbh4-0"]{content:"hOfjFo,oDGAe,kowOcT,gISSDQ,cEmWSE,hPvFuC,fFSoPl,bTBnTW,bHLmSv,iKqMNA,FxAyp,leYMvG,KMPzq,hfKjHv,gZWyZE,dwYKDk,ibcGmb,hKaEJF,XosP,bCKfWo,gUkoLg,dmxRgG,bZBlpz,lhTYNA,dbrgmi,dHJiml,cEytCf,fzFXnm,iMnkmv,ghzDag,kHuKdh,kgiVEz,jGhzSQ,faNtbn,fmQaBv,dwNhzn,fGwBZA,dJxjrT,eFxKDQ,dzCJzi,ldRxiI,fVkfyA,gNAmSV,jNEwzY,bsDwxw,jdLMhu,tOISc,hqwSEx,bDVoEr,kYLlPM,gYjEmn,kGqOLL,fHind,dnZoUW,jRZWlf,kTvpNk,iNMjfP,fefCSX,idgUkN,kcLCKF,kVWtTz,gWqxTd,ivobqY,iNRSob,ffkqe,hGyMdv,fGqKFv,eoaCFS,cCoXib,"}/*!sc*/ .eMMFM{min-width:0;}/*!sc*/ .eMMFM:where([data-size='small']){font-size:var(--text-body-size-small,0.75rem);line-height:var(--text-body-lineHeight-small,1.6666);}/*!sc*/ .eMMFM:where([data-size='medium']){font-size:var(--text-body-size-medium,0.875rem);line-height:var(--text-body-lineHeight-medium,1.4285);}/*!sc*/ .eMMFM:where([data-size='large']){font-size:var(--text-body-size-large,1rem);line-height:var(--text-body-lineHeight-large,1.5);}/*!sc*/ .eMMFM:where([data-weight='light']){font-weight:var(--base-text-weight-light,300);}/*!sc*/ .eMMFM:where([data-weight='normal']){font-weight:var(--base-text-weight-normal,400);}/*!sc*/ .eMMFM:where([data-weight='medium']){font-weight:var(--base-text-weight-medium,500);}/*!sc*/ .eMMFM:where([data-weight='semibold']){font-weight:var(--base-text-weight-semibold,600);}/*!sc*/ .HlHVj{padding-left:4px;padding-right:4px;font-weight:400;color:var(--fgColor-muted,var(--color-fg-muted,#656d76));font-size:16px;}/*!sc*/ .HlHVj:where([data-size='small']){font-size:var(--text-body-size-small,0.75rem);line-height:var(--text-body-lineHeight-small,1.6666);}/*!sc*/ .HlHVj:where([data-size='medium']){font-size:var(--text-body-size-medium,0.875rem);line-height:var(--text-body-lineHeight-medium,1.4285);}/*!sc*/ .HlHVj:where([data-size='large']){font-size:var(--text-body-size-large,1rem);line-height:var(--text-body-lineHeight-large,1.5);}/*!sc*/ .HlHVj:where([data-weight='light']){font-weight:var(--base-text-weight-light,300);}/*!sc*/ .HlHVj:where([data-weight='normal']){font-weight:var(--base-text-weight-normal,400);}/*!sc*/ .HlHVj:where([data-weight='medium']){font-weight:var(--base-text-weight-medium,500);}/*!sc*/ .HlHVj:where([data-weight='semibold']){font-weight:var(--base-text-weight-semibold,600);}/*!sc*/ .lauzFl{padding-left:4px;padding-right:4px;font-weight:400;color:var(--fgColor-muted,var(--color-fg-muted,#656d76));font-size:14px;}/*!sc*/ .lauzFl:where([data-size='small']){font-size:var(--text-body-size-small,0.75rem);line-height:var(--text-body-lineHeight-small,1.6666);}/*!sc*/ .lauzFl:where([data-size='medium']){font-size:var(--text-body-size-medium,0.875rem);line-height:var(--text-body-lineHeight-medium,1.4285);}/*!sc*/ .lauzFl:where([data-size='large']){font-size:var(--text-body-size-large,1rem);line-height:var(--text-body-lineHeight-large,1.5);}/*!sc*/ .lauzFl:where([data-weight='light']){font-weight:var(--base-text-weight-light,300);}/*!sc*/ .lauzFl:where([data-weight='normal']){font-weight:var(--base-text-weight-normal,400);}/*!sc*/ .lauzFl:where([data-weight='medium']){font-weight:var(--base-text-weight-medium,500);}/*!sc*/ .lauzFl:where([data-weight='semibold']){font-weight:var(--base-text-weight-semibold,600);}/*!sc*/ data-styled.g3[id="Text__StyledText-sc-17v1xeu-0"]{content:"eMMFM,HlHVj,lauzFl,"}/*!sc*/ .jkNcAv{border:0;font-size:inherit;font-family:inherit;background-color:transparent;-webkit-appearance:none;color:inherit;width:100%;}/*!sc*/ .jkNcAv:focus{outline:0;}/*!sc*/ data-styled.g13[id="UnstyledTextInput__ToggledUnstyledTextInput-sc-14ypya-0"]{content:"jkNcAv,"}/*!sc*/ .hLzFvi{font-size:14px;line-height:var(--base-size-20);color:var(--fgColor-default,var(--color-fg-default,#1F2328));vertical-align:middle;background-color:var(--bgColor-default,var(--color-canvas-default,#ffffff));border:1px solid var(--control-borderColor-rest,var(--borderColor-default,var(--color-border-default,#d0d7de)));border-radius:6px;outline:none;box-shadow:var(--shadow-inset,var(--color-primer-shadow-inset,inset 0 1px 0 rgba(208,215,222,0.2)));display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:stretch;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;min-height:var(--base-size-32);overflow:hidden;--inner-action-size:var(--base-size-24);}/*!sc*/ .hLzFvi input,.hLzFvi textarea{cursor:text;}/*!sc*/ .hLzFvi select{cursor:pointer;}/*!sc*/ .hLzFvi input::-webkit-input-placeholder,.hLzFvi textarea::-webkit-input-placeholder,.hLzFvi select::-webkit-input-placeholder{color:var(---control-fgColor-placeholder,var(--fgColor-muted,var(--color-fg-muted,#656d76)));}/*!sc*/ .hLzFvi input::-moz-placeholder,.hLzFvi textarea::-moz-placeholder,.hLzFvi select::-moz-placeholder{color:var(---control-fgColor-placeholder,var(--fgColor-muted,var(--color-fg-muted,#656d76)));}/*!sc*/ .hLzFvi input:-ms-input-placeholder,.hLzFvi textarea:-ms-input-placeholder,.hLzFvi select:-ms-input-placeholder{color:var(---control-fgColor-placeholder,var(--fgColor-muted,var(--color-fg-muted,#656d76)));}/*!sc*/ .hLzFvi input::placeholder,.hLzFvi textarea::placeholder,.hLzFvi select::placeholder{color:var(---control-fgColor-placeholder,var(--fgColor-muted,var(--color-fg-muted,#656d76)));}/*!sc*/ .hLzFvi:where([data-trailing-action][data-focused]),.hLzFvi:where(:not([data-trailing-action]):focus-within){border-color:var(--fgColor-accent,var(--color-accent-fg,#0969da));outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#0969da));outline-offset:-1px;}/*!sc*/ .hLzFvi > textarea{padding:var(--base-size-12);}/*!sc*/ .hLzFvi:where([data-contrast]){background-color:var(--bgColor-inset,var(--color-canvas-inset,#f6f8fa));}/*!sc*/ .hLzFvi:where([data-disabled]){color:var(--fgColor-disabled,var(--color-primer-fg-disabled,#8c959f));background-color:var(--control-bgColor-disabled,var(--color-input-disabled-bg,rgba(175,184,193,0.2)));box-shadow:none;border-color:var(--control-borderColor-disabled,var(--borderColor-default,var(--color-border-default,#d0d7de)));}/*!sc*/ .hLzFvi:where([data-disabled]) input,.hLzFvi:where([data-disabled]) textarea,.hLzFvi:where([data-disabled]) select{cursor:not-allowed;}/*!sc*/ .hLzFvi:where([data-monospace]){font-family:var(--fontStack-monospace,SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace);}/*!sc*/ .hLzFvi:where([data-validation='error']){border-color:var(--borderColor-danger-emphasis,var(--color-danger-emphasis,#cf222e));}/*!sc*/ .hLzFvi:where([data-validation='error']):where([data-trailing-action][data-focused]),.hLzFvi:where([data-validation='error']):where(:not([data-trailing-action])):focus-within{border-color:var(--fgColor-accent,var(--color-accent-fg,#0969da));outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#0969da));outline-offset:-1px;}/*!sc*/ .hLzFvi:where([data-validation='success']){border-color:var(--bgColor-success-emphasis,var(--color-success-emphasis,#1f883d));}/*!sc*/ .hLzFvi:where([data-block]){width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-self:stretch;-ms-flex-item-align:stretch;align-self:stretch;}/*!sc*/ @media (min-width:768px){.hLzFvi{font-size:var(--text-body-size-medium);}}/*!sc*/ .hLzFvi:where([data-size='small']){--inner-action-size:var(--base-size-20);min-height:var(--base-size-28);padding-top:3px;padding-right:var(--base-size-8);padding-bottom:3px;padding-left:var(--base-size-8);font-size:var(--text-body-size-small);line-height:var(--base-size-20);}/*!sc*/ .hLzFvi:where([data-size='large']){--inner-action-size:var(--base-size-28);height:var(--base-size-40);padding-top:10px;padding-right:var(--base-size-8);padding-bottom:10px;padding-left:var(--base-size-8);}/*!sc*/ .hLzFvi:where([data-variant='small']){min-height:28px;padding-top:3px;padding-right:var(--base-size-8);padding-bottom:3px;padding-left:var(--base-size-8);font-size:(--text-body-size-small);line-height:var(--base-size-20);}/*!sc*/ .hLzFvi:where([data-variant='large']){padding-top:10px;padding-right:var(--base-size-8);padding-bottom:10px;padding-left:var(--base-size-8);font-size:var(--text-title-size-medium);}/*!sc*/ .hLzFvi{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;min-width:160px;}/*!sc*/ data-styled.g14[id="TextInputWrapper__StyledTextInputBaseWrapper-sc-1mqhpbi-0"]{content:"hLzFvi,"}/*!sc*/ .iHYdQq{background-repeat:no-repeat;background-position:right 8px center;padding-right:0;padding-left:0;}/*!sc*/ .iHYdQq > :not(:last-child){margin-right:8px;}/*!sc*/ .iHYdQq .TextInput-icon,.iHYdQq .TextInput-action{-webkit-align-self:center;-ms-flex-item-align:center;align-self:center;color:var(--fgColor-muted,var(--color-fg-muted,#656d76));-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}/*!sc*/ .iHYdQq > input,.iHYdQq > select{padding-right:0;padding-left:0;}/*!sc*/ .iHYdQq:where([data-leading-visual]){padding-left:var(--base-size-12);}/*!sc*/ .iHYdQq:where([data-trailing-visual]:not([data-trailing-action])){padding-right:var(--base-size-12);}/*!sc*/ .iHYdQq:where(:not([data-leading-visual])) > input,.iHYdQq:where(:not([data-leading-visual])) > select{padding-left:var(--base-size-12);}/*!sc*/ .iHYdQq:where(:not([data-trailing-visual]):not([data-trailing-action])) > input,.iHYdQq:where(:not([data-trailing-visual]):not([data-trailing-action])) > select{padding-right:var(--base-size-12);}/*!sc*/ .iHYdQq{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;min-width:160px;}/*!sc*/ data-styled.g15[id="TextInputWrapper__StyledTextInputWrapper-sc-1mqhpbi-1"]{content:"iHYdQq,"}/*!sc*/ .jOyaRH{display:none;}/*!sc*/ .jOyaRH[popover]{position:absolute;padding:0.5em 0.75em;width:-webkit-max-content;width:-moz-max-content;width:max-content;margin:auto;-webkit-clip:auto;clip:auto;white-space:normal;font:normal normal 11px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";-webkit-font-smoothing:subpixel-antialiased;color:var(--tooltip-fgColor,var(--fgColor-onEmphasis,var(--color-fg-on-emphasis,#ffffff)));text-align:center;word-wrap:break-word;background:var(--tooltip-bgColor,var(--bgColor-emphasis,var(--color-neutral-emphasis-plus,#24292f)));border-radius:6px;border:0;opacity:0;max-width:250px;inset:auto;overflow:visible;}/*!sc*/ .jOyaRH[popover]:popover-open{display:block;}/*!sc*/ .jOyaRH[popover].\:popover-open{display:block;}/*!sc*/ @media (forced-colors:active){.jOyaRH{outline:1px solid transparent;}}/*!sc*/ .jOyaRH::after{position:absolute;display:block;right:0;left:0;height:var(--overlay-offset,0.25rem);content:'';}/*!sc*/ .jOyaRH[data-direction='n']::after,.jOyaRH[data-direction='ne']::after,.jOyaRH[data-direction='nw']::after{top:100%;}/*!sc*/ .jOyaRH[data-direction='s']::after,.jOyaRH[data-direction='se']::after,.jOyaRH[data-direction='sw']::after{bottom:100%;}/*!sc*/ .jOyaRH[data-direction='w']::after{position:absolute;display:block;height:100%;width:8px;content:'';bottom:0;left:100%;}/*!sc*/ .jOyaRH[data-direction='e']::after{position:absolute;display:block;height:100%;width:8px;content:'';bottom:0;right:100%;margin-left:-8px;}/*!sc*/ @-webkit-keyframes tooltip-appear{from{opacity:0;}to{opacity:1;}}/*!sc*/ @keyframes tooltip-appear{from{opacity:0;}to{opacity:1;}}/*!sc*/ .jOyaRH:popover-open,.jOyaRH:popover-open::before{-webkit-animation-name:tooltip-appear;animation-name:tooltip-appear;-webkit-animation-duration:0.1s;animation-duration:0.1s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;-webkit-animation-delay:0s;animation-delay:0s;}/*!sc*/ .jOyaRH.\:popover-open,.jOyaRH.\:popover-open::before{-webkit-animation-name:tooltip-appear;animation-name:tooltip-appear;-webkit-animation-duration:0.1s;animation-duration:0.1s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;-webkit-animation-delay:0s;animation-delay:0s;}/*!sc*/ data-styled.g16[id="Tooltip__StyledTooltip-sc-e45c7z-0"]{content:"jOyaRH,"}/*!sc*/ .hWlpPn{position:relative;display:inline-block;}/*!sc*/ .hWlpPn::after{position:absolute;z-index:1000000;display:none;padding:0.5em 0.75em;font:normal normal 11px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";-webkit-font-smoothing:subpixel-antialiased;color:var(--tooltip-fgColor,var(--fgColor-onEmphasis,var(--color-fg-on-emphasis,#ffffff)));text-align:center;-webkit-text-decoration:none;text-decoration:none;text-shadow:none;text-transform:none;-webkit-letter-spacing:normal;-moz-letter-spacing:normal;-ms-letter-spacing:normal;letter-spacing:normal;word-wrap:break-word;white-space:pre;pointer-events:none;content:attr(aria-label);background:var(--tooltip-bgColor,var(--bgColor-emphasis,var(--color-neutral-emphasis-plus,#24292f)));border-radius:6px;opacity:0;}/*!sc*/ @-webkit-keyframes tooltip-appear{from{opacity:0;}to{opacity:1;}}/*!sc*/ @keyframes tooltip-appear{from{opacity:0;}to{opacity:1;}}/*!sc*/ .hWlpPn:hover::after,.hWlpPn:active::after,.hWlpPn:focus::after,.hWlpPn:focus-within::after{display:inline-block;-webkit-text-decoration:none;text-decoration:none;-webkit-animation-name:tooltip-appear;animation-name:tooltip-appear;-webkit-animation-duration:0.1s;animation-duration:0.1s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;-webkit-animation-delay:0s;animation-delay:0s;}/*!sc*/ .hWlpPn.tooltipped-no-delay:hover::after,.hWlpPn.tooltipped-no-delay:active::after,.hWlpPn.tooltipped-no-delay:focus::after,.hWlpPn.tooltipped-no-delay:focus-within::after{-webkit-animation-delay:0s;animation-delay:0s;}/*!sc*/ .hWlpPn.tooltipped-multiline:hover::after,.hWlpPn.tooltipped-multiline:active::after,.hWlpPn.tooltipped-multiline:focus::after,.hWlpPn.tooltipped-multiline:focus-within::after{display:table-cell;}/*!sc*/ .hWlpPn.tooltipped-s::after,.hWlpPn.tooltipped-se::after,.hWlpPn.tooltipped-sw::after{top:100%;right:50%;margin-top:6px;}/*!sc*/ .hWlpPn.tooltipped-se::after{right:auto;left:50%;margin-left:-16px;}/*!sc*/ .hWlpPn.tooltipped-sw::after{margin-right:-16px;}/*!sc*/ .hWlpPn.tooltipped-n::after,.hWlpPn.tooltipped-ne::after,.hWlpPn.tooltipped-nw::after{right:50%;bottom:100%;margin-bottom:6px;}/*!sc*/ .hWlpPn.tooltipped-ne::after{right:auto;left:50%;margin-left:-16px;}/*!sc*/ .hWlpPn.tooltipped-nw::after{margin-right:-16px;}/*!sc*/ .hWlpPn.tooltipped-s::after,.hWlpPn.tooltipped-n::after{-webkit-transform:translateX(50%);-ms-transform:translateX(50%);transform:translateX(50%);}/*!sc*/ .hWlpPn.tooltipped-w::after{right:100%;bottom:50%;margin-right:6px;-webkit-transform:translateY(50%);-ms-transform:translateY(50%);transform:translateY(50%);}/*!sc*/ .hWlpPn.tooltipped-e::after{bottom:50%;left:100%;margin-left:6px;-webkit-transform:translateY(50%);-ms-transform:translateY(50%);transform:translateY(50%);}/*!sc*/ .hWlpPn.tooltipped-multiline::after{width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:250px;word-wrap:break-word;white-space:pre-line;border-collapse:separate;}/*!sc*/ .hWlpPn.tooltipped-multiline.tooltipped-s::after,.hWlpPn.tooltipped-multiline.tooltipped-n::after{right:auto;left:50%;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);}/*!sc*/ .hWlpPn.tooltipped-multiline.tooltipped-w::after,.hWlpPn.tooltipped-multiline.tooltipped-e::after{right:100%;}/*!sc*/ .hWlpPn.tooltipped-align-right-2::after{right:0;margin-right:0;}/*!sc*/ .hWlpPn.tooltipped-align-left-2::after{left:0;margin-left:0;}/*!sc*/ data-styled.g17[id="Tooltip__TooltipBase-sc-17tf59c-0"]{content:"hWlpPn,"}/*!sc*/ .eAtkQz{display:inline-block;overflow:hidden;text-overflow:ellipsis;vertical-align:top;white-space:nowrap;max-width:125px;max-width:100%;}/*!sc*/ data-styled.g19[id="Truncate__StyledTruncate-sc-23o1d2-0"]{content:"eAtkQz,"}/*!sc*/ .dwImxt{--segmented-control-button-inner-padding:12px;--segmented-control-button-bg-inset:4px;--segmented-control-outer-radius:6px;background-color:transparent;border-color:transparent;border-radius:var(--segmented-control-outer-radius);border-width:0;color:currentColor;cursor:pointer;font-family:inherit;font-size:inherit;font-weight:600;padding:0;height:100%;width:100%;}/*!sc*/ .dwImxt:focus:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#0969da));outline-offset:-1px;}/*!sc*/ .dwImxt:focus:not(:disabled):not(:focus-visible){outline:solid 1px transparent;}/*!sc*/ .dwImxt:focus-visible:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#0969da));outline-offset:-1px;}/*!sc*/ .dwImxt .segmentedControl-content{-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background-color:var(--controlKnob-bgColor-rest,var(--color-segmented-control-button-bg,#ffffff));border-color:var(--controlKnob-borderColor-rest,var(--color-segmented-control-button-hover-active-selected-border,#8c959f));border-style:solid;border-width:1px;border-radius:var(--segmented-control-outer-radius);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;height:100%;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;padding-left:var(--segmented-control-button-inner-padding);padding-right:var(--segmented-control-button-inner-padding);}/*!sc*/ .dwImxt svg{fill:var(--fgColor-muted,var(--color-fg-muted,#656d76));}/*!sc*/ .dwImxt:focus:focus-visible:not(:last-child):after{width:0;}/*!sc*/ .dwImxt .segmentedControl-text:after{content:"Preview";display:block;font-weight:600;height:0;overflow:hidden;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;visibility:hidden;}/*!sc*/ @media (pointer:coarse){.dwImxt:before{content:"";position:absolute;left:0;right:0;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);top:50%;min-height:44px;}}/*!sc*/ .iFTkun{--segmented-control-button-inner-padding:12px;--segmented-control-button-bg-inset:4px;--segmented-control-outer-radius:6px;background-color:transparent;border-color:transparent;border-radius:var(--segmented-control-outer-radius);border-width:0;color:currentColor;cursor:pointer;font-family:inherit;font-size:inherit;font-weight:400;padding:var(--segmented-control-button-bg-inset);height:100%;width:100%;}/*!sc*/ .iFTkun:focus:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#0969da));outline-offset:-1px;}/*!sc*/ .iFTkun:focus:not(:disabled):not(:focus-visible){outline:solid 1px transparent;}/*!sc*/ .iFTkun:focus-visible:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#0969da));outline-offset:-1px;}/*!sc*/ .iFTkun .segmentedControl-content{-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background-color:transparent;border-color:transparent;border-style:solid;border-width:1px;border-radius:calc(var(--segmented-control-outer-radius) - var(--segmented-control-button-bg-inset) / 2);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;height:100%;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;padding-left:calc(var(--segmented-control-button-inner-padding) - var(--segmented-control-button-bg-inset));padding-right:calc(var(--segmented-control-button-inner-padding) - var(--segmented-control-button-bg-inset));}/*!sc*/ .iFTkun svg{fill:var(--fgColor-muted,var(--color-fg-muted,#656d76));}/*!sc*/ .iFTkun:hover .segmentedControl-content{background-color:var(--controlTrack-bgColor-hover,var(--color-segmented-control-button-hover-bg,rgba(175,184,193,0.2)));}/*!sc*/ .iFTkun:active .segmentedControl-content{background-color:var(--controlTrack-bgColor-active,var(--color-segmented-control-button-hover-active-bg,rgba(175,184,193,0.4)));}/*!sc*/ .iFTkun:focus:focus-visible:not(:last-child):after{width:0;}/*!sc*/ .iFTkun .segmentedControl-text:after{content:"Code";display:block;font-weight:600;height:0;overflow:hidden;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;visibility:hidden;}/*!sc*/ @media (pointer:coarse){.iFTkun:before{content:"";position:absolute;left:0;right:0;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);top:50%;min-height:44px;}}/*!sc*/ .bHmvop{--segmented-control-button-inner-padding:12px;--segmented-control-button-bg-inset:4px;--segmented-control-outer-radius:6px;background-color:transparent;border-color:transparent;border-radius:var(--segmented-control-outer-radius);border-width:0;color:currentColor;cursor:pointer;font-family:inherit;font-size:inherit;font-weight:400;padding:var(--segmented-control-button-bg-inset);height:100%;width:100%;}/*!sc*/ .bHmvop:focus:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#0969da));outline-offset:-1px;}/*!sc*/ .bHmvop:focus:not(:disabled):not(:focus-visible){outline:solid 1px transparent;}/*!sc*/ .bHmvop:focus-visible:not(:disabled){box-shadow:none;outline:2px solid var(--fgColor-accent,var(--color-accent-fg,#0969da));outline-offset:-1px;}/*!sc*/ .bHmvop .segmentedControl-content{-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background-color:transparent;border-color:transparent;border-style:solid;border-width:1px;border-radius:calc(var(--segmented-control-outer-radius) - var(--segmented-control-button-bg-inset) / 2);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;height:100%;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;padding-left:calc(var(--segmented-control-button-inner-padding) - var(--segmented-control-button-bg-inset));padding-right:calc(var(--segmented-control-button-inner-padding) - var(--segmented-control-button-bg-inset));}/*!sc*/ .bHmvop svg{fill:var(--fgColor-muted,var(--color-fg-muted,#656d76));}/*!sc*/ .bHmvop:hover .segmentedControl-content{background-color:var(--controlTrack-bgColor-hover,var(--color-segmented-control-button-hover-bg,rgba(175,184,193,0.2)));}/*!sc*/ .bHmvop:active .segmentedControl-content{background-color:var(--controlTrack-bgColor-active,var(--color-segmented-control-button-hover-active-bg,rgba(175,184,193,0.4)));}/*!sc*/ .bHmvop:focus:focus-visible:not(:last-child):after{width:0;}/*!sc*/ .bHmvop .segmentedControl-text:after{content:"Blame";display:block;font-weight:600;height:0;overflow:hidden;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;visibility:hidden;}/*!sc*/ @media (pointer:coarse){.bHmvop:before{content:"";position:absolute;left:0;right:0;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);top:50%;min-height:44px;}}/*!sc*/ data-styled.g105[id="SegmentedControlButton__SegmentedControlButtonStyled-sc-8lkgxl-0"]{content:"dwImxt,iFTkun,bHmvop,"}/*!sc*/ .lawgDG{background-color:var(--controlTrack-bgColor-rest,var(--color-segmented-control-bg,#eaeef2));border-radius:6px;border:1px solid;border-color:var(--controlTrack-borderColor-rest,transparent);display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;font-size:14px;height:28px;margin:0;padding:0;}/*!sc*/ data-styled.g107[id="SegmentedControl__SegmentedControlList-sc-1rzig82-0"]{content:"lawgDG,"}/*!sc*/ body[data-page-layout-dragging="true"]{cursor:col-resize;}/*!sc*/ body[data-page-layout-dragging="true"] *{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}/*!sc*/ data-styled.g108[id="sc-global-gbKrvU1"]{content:"sc-global-gbKrvU1,"}/*!sc*/ </style><meta data-hydrostats="publish"/> <!-- --> <!-- --> <button hidden="" data-testid="header-permalink-button" data-hotkey-scope="read-only-cursor-text-area"></button><button hidden=""></button><div><div style="--sticky-pane-height:100vh;--spacing:var(--spacing-none)" class="Box-sc-g0xbh4-0 hOfjFo"><div class="Box-sc-g0xbh4-0 oDGAe"><div class="Box-sc-g0xbh4-0 kowOcT"><div tabindex="0" class="Box-sc-g0xbh4-0 gISSDQ"><div class="Box-sc-g0xbh4-0 cEmWSE"><div class="Box-sc-g0xbh4-0 hPvFuC"></div><div style="--pane-width:320px" class="Box-sc-g0xbh4-0 fFSoPl"></div><div class="Box-sc-g0xbh4-0 bTBnTW"><div role="slider" aria-label="Draggable pane splitter" aria-valuemin="0" aria-valuemax="0" aria-valuenow="0" aria-valuetext="Pane width 0 pixels" tabindex="0" class="Box-sc-g0xbh4-0 bHLmSv"></div></div></div></div><div class="Box-sc-g0xbh4-0 iKqMNA"><div class="Box-sc-g0xbh4-0"></div><div class="Box-sc-g0xbh4-0 FxAyp"><div data-selector="repos-split-pane-content" tabindex="0" class="Box-sc-g0xbh4-0 leYMvG"><div class="Box-sc-g0xbh4-0 KMPzq"><div class="Box-sc-g0xbh4-0 hfKjHv container"><div class="px-3 pt-3 pb-0" id="StickyHeader"><div class="Box-sc-g0xbh4-0 gZWyZE"><div class="Box-sc-g0xbh4-0 dwYKDk"><div class="Box-sc-g0xbh4-0 ibcGmb react-code-view-header-wrap--narrow"><div class="Box-sc-g0xbh4-0 hKaEJF"><h2 class="Box-sc-g0xbh4-0 XosP prc-Heading-Heading-6CmGO"><button style="--button-color:fg.muted" type="button" aria-label="Expand file tree" data-testid="expand-file-tree-button-mobile" class="Box-sc-g0xbh4-0 bCKfWo prc-Button-ButtonBase-c50BI" data-loading="false" data-size="medium" data-variant="invisible" aria-describedby=":Rld9lab:-loading-announcement"><span data-component="buttonContent" class="Box-sc-g0xbh4-0 gUkoLg prc-Button-ButtonContent-HKbr-"><span data-component="leadingVisual" class="prc-Button-Visual-2epfX prc-Button-VisualWrap-Db-eB"><svg aria-hidden="true" focusable="false" class="octicon octicon-arrow-left" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="M7.78 12.53a.75.75 0 0 1-1.06 0L2.47 8.28a.75.75 0 0 1 0-1.06l4.25-4.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L4.81 7h7.44a.75.75 0 0 1 0 1.5H4.81l2.97 2.97a.75.75 0 0 1 0 1.06Z"></path></svg></span><span data-component="text" class="prc-Button-Label-pTQ3x">Files</span></span></button><span role="tooltip" aria-label="Expand file tree" id="expand-button-file-tree-button" class="Tooltip__TooltipBase-sc-17tf59c-0 hWlpPn tooltipped-se"><button data-component="IconButton" type="button" data-testid="expand-file-tree-button" aria-controls="repos-file-tree" class="prc-Button-ButtonBase-c50BI position-relative ExpandFileTreeButton-module__expandButton--gL4is ExpandFileTreeButton-module__filesButtonBreakpoint--WfX9t fgColor-muted prc-Button-IconButton-szpyj" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="invisible" aria-describedby=":R35d9lab:-loading-announcement" aria-labelledby="expand-button-file-tree-button"><svg aria-hidden="true" focusable="false" class="octicon octicon-sidebar-collapse" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="M6.823 7.823a.25.25 0 0 1 0 .354l-2.396 2.396A.25.25 0 0 1 4 10.396V5.604a.25.25 0 0 1 .427-.177Z"></path><path d="M1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25V1.75C0 .784.784 0 1.75 0ZM1.5 1.75v12.5c0 .138.112.25.25.25H9.5v-13H1.75a.25.25 0 0 0-.25.25ZM11 14.5h3.25a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25H11Z"></path></svg></button></span><button hidden="" data-testid="" data-hotkey-scope="read-only-cursor-text-area"></button></h2></div><div class="react-code-view-header-mb--narrow mr-2"><button type="button" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-label="main branch" data-testid="anchor-button" class="Box-sc-g0xbh4-0 dmxRgG prc-Button-ButtonBase-c50BI ref-selector-class" data-loading="false" data-size="medium" data-variant="default" aria-describedby="branch-picker-repos-header-ref-selector-wide-loading-announcement" id="branch-picker-repos-header-ref-selector-wide"><span data-component="buttonContent" class="Box-sc-g0xbh4-0 gUkoLg prc-Button-ButtonContent-HKbr-"><span data-component="text" class="prc-Button-Label-pTQ3x"><div class="Box-sc-g0xbh4-0 bZBlpz"><div class="Box-sc-g0xbh4-0 lhTYNA"><svg aria-hidden="true" focusable="false" class="octicon octicon-git-branch" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="M9.5 3.25a2.25 2.25 0 1 1 3 2.122V6A2.5 2.5 0 0 1 10 8.5H6a1 1 0 0 0-1 1v1.128a2.251 2.251 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.5 0v1.836A2.493 2.493 0 0 1 6 7h4a1 1 0 0 0 1-1v-.628A2.25 2.25 0 0 1 9.5 3.25Zm-6 0a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Zm8.25-.75a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5ZM4.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Z"></path></svg></div><div class="Box-sc-g0xbh4-0 dbrgmi ref-selector-button-text-container"><span class="Text__StyledText-sc-17v1xeu-0 eMMFM"> <!-- -->main</span></div></div></span><span data-component="trailingVisual" class="prc-Button-Visual-2epfX prc-Button-VisualWrap-Db-eB"><svg aria-hidden="true" focusable="false" class="octicon octicon-triangle-down" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z"></path></svg></span></span></button><button hidden="" data-hotkey-scope="read-only-cursor-text-area"></button></div><div class="Box-sc-g0xbh4-0 dHJiml react-code-view-header-mb--narrow"><div class="Box-sc-g0xbh4-0 cEytCf"><nav data-testid="breadcrumbs" aria-labelledby="repos-header-breadcrumb-heading" id="repos-header-breadcrumb" class="Box-sc-g0xbh4-0 fzFXnm"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone--vW4Cq prc-Heading-Heading-6CmGO" data-testid="screen-reader-heading" id="repos-header-breadcrumb-heading">Breadcrumbs</h2><ol class="Box-sc-g0xbh4-0 iMnkmv"><li class="Box-sc-g0xbh4-0 ghzDag"><a class="Box-sc-g0xbh4-0 kHuKdh prc-Link-Link-85e08" sx="[object Object]" data-testid="breadcrumbs-repo-link" href="/ampproject/amphtml/tree/main">amphtml</a></li><li class="Box-sc-g0xbh4-0 ghzDag"><span class="Text__StyledText-sc-17v1xeu-0 HlHVj" aria-hidden="true">/</span><a class="Box-sc-g0xbh4-0 kgiVEz prc-Link-Link-85e08" sx="[object Object]" href="/ampproject/amphtml/tree/main/extensions">extensions</a></li><li class="Box-sc-g0xbh4-0 ghzDag"><span class="Text__StyledText-sc-17v1xeu-0 HlHVj" aria-hidden="true">/</span><a class="Box-sc-g0xbh4-0 kgiVEz prc-Link-Link-85e08" sx="[object Object]" href="/ampproject/amphtml/tree/main/extensions/amp-a4a">amp-a4a</a></li></ol></nav><div data-testid="breadcrumbs-filename" class="Box-sc-g0xbh4-0 ghzDag"><span class="Text__StyledText-sc-17v1xeu-0 HlHVj" aria-hidden="true">/</span><h1 class="Box-sc-g0xbh4-0 jGhzSQ prc-Heading-Heading-6CmGO" tabindex="-1" id="file-name-id">rtc-documentation.md</h1></div><button data-component="IconButton" type="button" class="prc-Button-ButtonBase-c50BI ml-2 prc-Button-IconButton-szpyj" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-describedby=":Rftd9lab:-loading-announcement" aria-labelledby=":R1td9lab:"><svg aria-hidden="true" focusable="false" class="octicon octicon-copy" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button><span class="Tooltip__StyledTooltip-sc-e45c7z-0 jOyaRH CopyToClipboardButton-module__tooltip--Dq1IB" data-direction="nw" aria-label="Copy path" aria-hidden="true" id=":R1td9lab:">Copy path</span></div></div></div><div class="react-code-view-header-element--wide"><div class="Box-sc-g0xbh4-0 faNtbn"><div class="d-flex gap-2"> <div><div class="Box-sc-g0xbh4-0 fmQaBv"><span class="TextInputWrapper__StyledTextInputBaseWrapper-sc-1mqhpbi-0 hLzFvi TextInputWrapper__StyledTextInputWrapper-sc-1mqhpbi-1 iHYdQq TextInput-wrapper" data-leading-visual="true" data-trailing-visual="true" aria-busy="false"><span class="TextInput-icon" id=":R5j6d9lab:" aria-hidden="true"><svg aria-hidden="true" focusable="false" class="octicon octicon-search" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path></svg></span><input type="text" aria-label="Go to file" role="combobox" aria-controls="file-results-list" aria-expanded="false" aria-haspopup="dialog" autoCorrect="off" spellcheck="false" placeholder="Go to file" aria-describedby=":R5j6d9lab: :R5j6d9labH1:" data-component="input" class="UnstyledTextInput__ToggledUnstyledTextInput-sc-14ypya-0 jkNcAv" value=""/><span class="TextInput-icon" id=":R5j6d9labH1:" aria-hidden="true"></span></span></div><button hidden="" data-testid="" data-hotkey-scope="read-only-cursor-text-area"></button><button hidden=""></button></div><button type="button" class="Box-sc-g0xbh4-0 dwNhzn prc-Button-ButtonBase-c50BI" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default" aria-describedby=":R2l6d9lab:-loading-announcement"><span data-component="buttonContent" class="Box-sc-g0xbh4-0 gUkoLg prc-Button-ButtonContent-HKbr-"><span data-component="text" class="prc-Button-Label-pTQ3x">Blame</span></span></button><button hidden="" data-testid="" data-hotkey-scope="read-only-cursor-text-area"></button><button data-component="IconButton" type="button" aria-label="More file actions" title="More file actions" data-testid="more-file-actions-button-nav-menu-wide" aria-haspopup="true" aria-expanded="false" tabindex="0" class="Box-sc-g0xbh4-0 fGwBZA prc-Button-ButtonBase-c50BI js-blob-dropdown-click prc-Button-IconButton-szpyj" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default" aria-describedby=":R156d9lab:-loading-announcement" id=":R156d9lab:"><svg aria-hidden="true" focusable="false" class="octicon octicon-kebab-horizontal" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path></svg></button> </div></div></div><div class="react-code-view-header-element--narrow"><div class="Box-sc-g0xbh4-0 faNtbn"><div class="d-flex gap-2"> <button type="button" class="Box-sc-g0xbh4-0 dwNhzn prc-Button-ButtonBase-c50BI" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default" aria-describedby=":R2l7d9lab:-loading-announcement"><span data-component="buttonContent" class="Box-sc-g0xbh4-0 gUkoLg prc-Button-ButtonContent-HKbr-"><span data-component="text" class="prc-Button-Label-pTQ3x">Blame</span></span></button><button hidden="" data-testid="" data-hotkey-scope="read-only-cursor-text-area"></button><button data-component="IconButton" type="button" aria-label="More file actions" title="More file actions" data-testid="more-file-actions-button-nav-menu-narrow" aria-haspopup="true" aria-expanded="false" tabindex="0" class="Box-sc-g0xbh4-0 fGwBZA prc-Button-ButtonBase-c50BI js-blob-dropdown-click prc-Button-IconButton-szpyj" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default" aria-describedby=":R157d9lab:-loading-announcement" id=":R157d9lab:"><svg aria-hidden="true" focusable="false" class="octicon octicon-kebab-horizontal" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path></svg></button> </div></div></div></div></div></div></div></div><div class="Box-sc-g0xbh4-0 dJxjrT react-code-view-bottom-padding"> <div class="Box-sc-g0xbh4-0 eFxKDQ"></div> <!-- --> <!-- --> </div><div class="Box-sc-g0xbh4-0 dJxjrT"> <!-- --> <!-- --> <button hidden="" data-testid="" data-hotkey-scope="read-only-cursor-text-area"></button><button hidden=""></button><div class="d-flex flex-column border rounded-2 mb-3 pl-1"><div class="Box-sc-g0xbh4-0 dzCJzi"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone--vW4Cq prc-Heading-Heading-6CmGO" data-testid="screen-reader-heading">Latest commit</h2><div style="width:120px" class="Skeleton Skeleton--text" data-testid="loading"> </div><div class="d-flex flex-shrink-0 gap-2"><div data-testid="latest-commit-details" class="d-none d-sm-flex flex-items-center"></div><div class="d-flex gap-2"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone--vW4Cq prc-Heading-Heading-6CmGO" data-testid="screen-reader-heading">History</h2><a href="/ampproject/amphtml/commits/main/extensions/amp-a4a/rtc-documentation.md" class="prc-Button-ButtonBase-c50BI d-none d-lg-flex LinkButton-module__code-view-link-button--xvCGA flex-items-center fgColor-default" data-loading="false" data-size="small" data-variant="invisible" aria-describedby=":R5dlal9lab:-loading-announcement"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-HKbr-"><span data-component="leadingVisual" class="prc-Button-Visual-2epfX prc-Button-VisualWrap-Db-eB"><svg aria-hidden="true" focusable="false" class="octicon octicon-history" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="m.427 1.927 1.215 1.215a8.002 8.002 0 1 1-1.6 5.685.75.75 0 1 1 1.493-.154 6.5 6.5 0 1 0 1.18-4.458l1.358 1.358A.25.25 0 0 1 3.896 6H.25A.25.25 0 0 1 0 5.75V2.104a.25.25 0 0 1 .427-.177ZM7.75 4a.75.75 0 0 1 .75.75v2.992l2.028.812a.75.75 0 0 1-.557 1.392l-2.5-1A.751.751 0 0 1 7 8.25v-3.5A.75.75 0 0 1 7.75 4Z"></path></svg></span><span data-component="text" class="prc-Button-Label-pTQ3x"><span class="fgColor-default">History</span></span></span></a><div class="d-sm-none"></div><div class="d-flex d-lg-none"><span role="tooltip" aria-label="History" id="history-icon-button-tooltip" class="Tooltip__TooltipBase-sc-17tf59c-0 hWlpPn tooltipped-n"><a href="/ampproject/amphtml/commits/main/extensions/amp-a4a/rtc-documentation.md" class="prc-Button-ButtonBase-c50BI LinkButton-module__code-view-link-button--xvCGA flex-items-center fgColor-default" data-loading="false" data-size="small" data-variant="invisible" aria-describedby=":Rpdlal9lab:-loading-announcement history-icon-button-tooltip"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-HKbr-"><span data-component="leadingVisual" class="prc-Button-Visual-2epfX prc-Button-VisualWrap-Db-eB"><svg aria-hidden="true" focusable="false" class="octicon octicon-history" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="m.427 1.927 1.215 1.215a8.002 8.002 0 1 1-1.6 5.685.75.75 0 1 1 1.493-.154 6.5 6.5 0 1 0 1.18-4.458l1.358 1.358A.25.25 0 0 1 3.896 6H.25A.25.25 0 0 1 0 5.75V2.104a.25.25 0 0 1 .427-.177ZM7.75 4a.75.75 0 0 1 .75.75v2.992l2.028.812a.75.75 0 0 1-.557 1.392l-2.5-1A.751.751 0 0 1 7 8.25v-3.5A.75.75 0 0 1 7.75 4Z"></path></svg></span></span></a></span></div></div></div></div></div><div class="Box-sc-g0xbh4-0 ldRxiI"><div class="Box-sc-g0xbh4-0 fVkfyA container"><div class="Box-sc-g0xbh4-0 gNAmSV react-code-size-details-banner"><div class="Box-sc-g0xbh4-0 jNEwzY react-code-size-details-banner"><div class="Box-sc-g0xbh4-0 bsDwxw text-mono"><div title="37.8 KB" data-testid="blob-size" class="Truncate__StyledTruncate-sc-23o1d2-0 eAtkQz"><span>861 lines (673 loc) · 37.8 KB</span></div></div></div></div><div class="Box-sc-g0xbh4-0 jdLMhu react-blob-view-header-sticky" id="repos-sticky-header"><div class="Box-sc-g0xbh4-0 tOISc"><div class="react-blob-sticky-header"><div class="Box-sc-g0xbh4-0 hqwSEx"><div class="Box-sc-g0xbh4-0 bDVoEr"><div class="Box-sc-g0xbh4-0 kYLlPM"><div class="Box-sc-g0xbh4-0 gYjEmn"><button type="button" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-label="main branch" data-testid="anchor-button" class="Box-sc-g0xbh4-0 dmxRgG prc-Button-ButtonBase-c50BI ref-selector-class" data-loading="false" data-size="medium" data-variant="default" aria-describedby="branch-picker-repos-header-ref-selector-loading-announcement" id="branch-picker-repos-header-ref-selector"><span data-component="buttonContent" class="Box-sc-g0xbh4-0 gUkoLg prc-Button-ButtonContent-HKbr-"><span data-component="text" class="prc-Button-Label-pTQ3x"><div class="Box-sc-g0xbh4-0 bZBlpz"><div class="Box-sc-g0xbh4-0 lhTYNA"><svg aria-hidden="true" focusable="false" class="octicon octicon-git-branch" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="M9.5 3.25a2.25 2.25 0 1 1 3 2.122V6A2.5 2.5 0 0 1 10 8.5H6a1 1 0 0 0-1 1v1.128a2.251 2.251 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.5 0v1.836A2.493 2.493 0 0 1 6 7h4a1 1 0 0 0 1-1v-.628A2.25 2.25 0 0 1 9.5 3.25Zm-6 0a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Zm8.25-.75a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5ZM4.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Z"></path></svg></div><div class="Box-sc-g0xbh4-0 dbrgmi ref-selector-button-text-container"><span class="Text__StyledText-sc-17v1xeu-0 eMMFM"> <!-- -->main</span></div></div></span><span data-component="trailingVisual" class="prc-Button-Visual-2epfX prc-Button-VisualWrap-Db-eB"><svg aria-hidden="true" focusable="false" class="octicon octicon-triangle-down" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z"></path></svg></span></span></button><button hidden="" data-hotkey-scope="read-only-cursor-text-area"></button></div><div class="Box-sc-g0xbh4-0 kGqOLL"><div class="Box-sc-g0xbh4-0 fHind"><nav data-testid="breadcrumbs" aria-labelledby="sticky-breadcrumb-heading" id="sticky-breadcrumb" class="Box-sc-g0xbh4-0 fzFXnm"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone--vW4Cq prc-Heading-Heading-6CmGO" data-testid="screen-reader-heading" id="sticky-breadcrumb-heading">Breadcrumbs</h2><ol class="Box-sc-g0xbh4-0 iMnkmv"><li class="Box-sc-g0xbh4-0 ghzDag"><a class="Box-sc-g0xbh4-0 kHuKdh prc-Link-Link-85e08" sx="[object Object]" data-testid="breadcrumbs-repo-link" href="/ampproject/amphtml/tree/main">amphtml</a></li><li class="Box-sc-g0xbh4-0 ghzDag"><span class="Text__StyledText-sc-17v1xeu-0 lauzFl" aria-hidden="true">/</span><a class="Box-sc-g0xbh4-0 kgiVEz prc-Link-Link-85e08" sx="[object Object]" href="/ampproject/amphtml/tree/main/extensions">extensions</a></li><li class="Box-sc-g0xbh4-0 ghzDag"><span class="Text__StyledText-sc-17v1xeu-0 lauzFl" aria-hidden="true">/</span><a class="Box-sc-g0xbh4-0 kgiVEz prc-Link-Link-85e08" sx="[object Object]" href="/ampproject/amphtml/tree/main/extensions/amp-a4a">amp-a4a</a></li></ol></nav><div data-testid="breadcrumbs-filename" class="Box-sc-g0xbh4-0 ghzDag"><span class="Text__StyledText-sc-17v1xeu-0 lauzFl" aria-hidden="true">/</span><h1 class="Box-sc-g0xbh4-0 dnZoUW prc-Heading-Heading-6CmGO" tabindex="-1" id="sticky-file-name-id">rtc-documentation.md</h1></div></div></div></div><button style="--button-color:fg.default" type="button" class="Box-sc-g0xbh4-0 jRZWlf prc-Button-ButtonBase-c50BI" data-loading="false" data-size="small" data-variant="invisible" aria-describedby=":Riptal9lab:-loading-announcement"><span data-component="buttonContent" class="Box-sc-g0xbh4-0 gUkoLg prc-Button-ButtonContent-HKbr-"><span data-component="leadingVisual" class="prc-Button-Visual-2epfX prc-Button-VisualWrap-Db-eB"><svg aria-hidden="true" focusable="false" class="octicon octicon-arrow-up" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="M3.47 7.78a.75.75 0 0 1 0-1.06l4.25-4.25a.75.75 0 0 1 1.06 0l4.25 4.25a.751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018L9 4.81v7.44a.75.75 0 0 1-1.5 0V4.81L4.53 7.78a.75.75 0 0 1-1.06 0Z"></path></svg></span><span data-component="text" class="prc-Button-Label-pTQ3x">Top</span></span></button></div></div></div><div class="Box-sc-g0xbh4-0 kTvpNk"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone--vW4Cq prc-Heading-Heading-6CmGO" data-testid="screen-reader-heading">File metadata and controls</h2><div class="Box-sc-g0xbh4-0 iNMjfP"><ul aria-label="File view" class="SegmentedControl__SegmentedControlList-sc-1rzig82-0 lawgDG" data-size="small"><li class="Box-sc-g0xbh4-0 fefCSX" data-selected="true"><button aria-current="true" class="SegmentedControlButton__SegmentedControlButtonStyled-sc-8lkgxl-0 dwImxt" type="button"><span class="segmentedControl-content"><div class="Box-sc-g0xbh4-0 segmentedControl-text" data-text="Preview">Preview</div></span></button></li><li class="Box-sc-g0xbh4-0 idgUkN"><button aria-current="false" class="SegmentedControlButton__SegmentedControlButtonStyled-sc-8lkgxl-0 iFTkun" type="button"><span class="segmentedControl-content"><div class="Box-sc-g0xbh4-0 segmentedControl-text" data-text="Code">Code</div></span></button></li><li class="Box-sc-g0xbh4-0 idgUkN"><button aria-current="false" class="SegmentedControlButton__SegmentedControlButtonStyled-sc-8lkgxl-0 bHmvop" type="button"><span class="segmentedControl-content"><div class="Box-sc-g0xbh4-0 segmentedControl-text" data-text="Blame">Blame</div></span></button></li></ul><button hidden="" data-testid="" data-hotkey-scope="read-only-cursor-text-area"></button><button hidden="" data-testid="" data-hotkey-scope="read-only-cursor-text-area"></button><button hidden="" data-testid="" data-hotkey-scope="read-only-cursor-text-area"></button><div class="Box-sc-g0xbh4-0 jNEwzY react-code-size-details-in-header"><div class="Box-sc-g0xbh4-0 bsDwxw text-mono"><div title="37.8 KB" data-testid="blob-size" class="Truncate__StyledTruncate-sc-23o1d2-0 eAtkQz"><span>861 lines (673 loc) · 37.8 KB</span></div></div></div></div><div class="Box-sc-g0xbh4-0 kcLCKF"><div class="Box-sc-g0xbh4-0 kVWtTz react-blob-header-edit-and-raw-actions"><div class="Box-sc-g0xbh4-0 prc-ButtonGroup-ButtonGroup-vcMeG"><div><a href="https://github.com/ampproject/amphtml/raw/refs/heads/main/extensions/amp-a4a/rtc-documentation.md" data-testid="raw-button" class="Box-sc-g0xbh4-0 gWqxTd prc-Button-ButtonBase-c50BI" data-loading="false" data-no-visuals="true" data-size="small" data-variant="default" aria-describedby=":R5csptal9lab:-loading-announcement"><span data-component="buttonContent" class="Box-sc-g0xbh4-0 gUkoLg prc-Button-ButtonContent-HKbr-"><span data-component="text" class="prc-Button-Label-pTQ3x">Raw</span></span></a></div><div><button data-component="IconButton" type="button" aria-label="Copy raw content" data-testid="copy-raw-button" class="prc-Button-ButtonBase-c50BI prc-Button-IconButton-szpyj" data-loading="false" data-no-visuals="true" data-size="small" data-variant="default" aria-describedby=":Rpcsptal9lab:-loading-announcement"><svg aria-hidden="true" focusable="false" class="octicon octicon-copy" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button></div><div><span role="tooltip" aria-label="Download raw file" id=":Rdcsptal9lab:" class="Tooltip__TooltipBase-sc-17tf59c-0 hWlpPn tooltipped-n"><button data-component="IconButton" type="button" aria-label="Download raw content" data-testid="download-raw-button" class="Box-sc-g0xbh4-0 ivobqY prc-Button-ButtonBase-c50BI prc-Button-IconButton-szpyj" data-loading="false" data-no-visuals="true" data-size="small" data-variant="default" aria-describedby=":Rtcsptal9lab:-loading-announcement"><svg aria-hidden="true" focusable="false" class="octicon octicon-download" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="M2.75 14A1.75 1.75 0 0 1 1 12.25v-2.5a.75.75 0 0 1 1.5 0v2.5c0 .138.112.25.25.25h10.5a.25.25 0 0 0 .25-.25v-2.5a.75.75 0 0 1 1.5 0v2.5A1.75 1.75 0 0 1 13.25 14Z"></path><path d="M7.25 7.689V2a.75.75 0 0 1 1.5 0v5.689l1.97-1.969a.749.749 0 1 1 1.06 1.06l-3.25 3.25a.749.749 0 0 1-1.06 0L4.22 6.78a.749.749 0 1 1 1.06-1.06l1.97 1.969Z"></path></svg></button></span></div></div><button hidden="" data-testid="raw-button-shortcut" data-hotkey-scope="read-only-cursor-text-area"></button><button hidden="" data-testid="copy-raw-button-shortcut" data-hotkey-scope="read-only-cursor-text-area"></button><button hidden="" data-testid="download-raw-button-shortcut" data-hotkey-scope="read-only-cursor-text-area"></button></div><button data-component="IconButton" type="button" aria-label="Outline" aria-pressed="false" class="Box-sc-g0xbh4-0 iNRSob prc-Button-ButtonBase-c50BI prc-Button-IconButton-szpyj" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-describedby=":R6sptal9lab:-loading-announcement"><svg aria-hidden="true" focusable="false" class="octicon octicon-list-unordered" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="M5.75 2.5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5Zm0 5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5Zm0 5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5ZM2 14a1 1 0 1 1 0-2 1 1 0 0 1 0 2Zm1-6a1 1 0 1 1-2 0 1 1 0 0 1 2 0ZM2 4a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path></svg></button><div class="react-blob-header-edit-and-raw-actions-combined"><button data-component="IconButton" type="button" aria-label="Edit and raw actions" title="More file actions" data-testid="more-file-actions-button" aria-haspopup="true" aria-expanded="false" tabindex="0" class="Box-sc-g0xbh4-0 ffkqe prc-Button-ButtonBase-c50BI js-blob-dropdown-click prc-Button-IconButton-szpyj" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-describedby=":Rnsptal9lab:-loading-announcement" id=":Rnsptal9lab:"><svg aria-hidden="true" focusable="false" class="octicon octicon-kebab-horizontal" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" style="display:inline-block;user-select:none;vertical-align:text-bottom;overflow:visible"><path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path></svg></button></div></div></div></div><div></div></div><div class="Box-sc-g0xbh4-0 hGyMdv"><section aria-labelledby="file-name-id-wide file-name-id-mobile" class="Box-sc-g0xbh4-0 fGqKFv"><div class="Box-sc-g0xbh4-0 eoaCFS js-snippet-clipboard-copy-unpositioned undefined" data-hpc="true"><article class="markdown-body entry-content container-lg" itemprop="text"><div class="markdown-heading" dir="auto"><h1 tabindex="-1" class="heading-element" dir="auto">AMP Real Time Config</h1><a id="user-content-amp-real-time-config" class="anchor" aria-label="Permalink: AMP Real Time Config" href="#amp-real-time-config"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Objective</h2><a id="user-content-objective" class="anchor" aria-label="Permalink: Objective" href="#objective"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">For AMP Fast Fetch, support publisher-specified, multiple, simultaneous callouts in order to augment targeting information included in the ad request.</p> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Background</h2><a id="user-content-background" class="anchor" aria-label="Permalink: Background" href="#background"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Remote HTML support was added for Delayed Fetch to support first-party cookie targeting. This was because AMP does not allow custom JavaScript, and pages served from the AMP cache are identical for each user. However, Remote HTML leverages the fact that custom JavaScript execution occurs as a part of generating an ad request via Delayed Fetch. Fast Fetch allows for sending the ad request early by moving all code related to ad generation within the AMP runtime, disallowing any custom JavaScript as part of ad request creation. Therefore Fast Fetch is incompatible with Remote HTML. Real Time Config (RTC) has been added as an optional feature of Fast Fetch to allow for publishers to add user-targeting information to ad requests from AMP pages in a generic way that can be utilized by any ad networks, and any user-targeting vendors. Common use cases for RTC are to retrieve 1st party or 3rd party data, or to integrate 3rd party demand, also known as Header Bidding.</p> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Overview</h2><a id="user-content-overview" class="anchor" aria-label="Permalink: Overview" href="#overview"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">The design of RTC is per-slot, with a <strong>maximum of 5 parallel callouts allowed per slot</strong>. RTC is usable by any Fast Fetch network implementation. Call-outs for all slots will be sent as soon as possible. There are two different types of callouts that will be supported:</p> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Custom URL callout</h3><a id="user-content-custom-url-callout" class="anchor" aria-label="Permalink: Custom URL callout" href="#custom-url-callout"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">The publisher specifies a custom URL that should be called out to. For example, a publisher may specify their own targeting server as a custom URL. If the ad network in use supports macro substitution for custom URLs, the publisher may specify macros in the URL. See the <a href="#url-macro-substitution">URL Macro Substitution</a> section for details.</p> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Vendor-specified URL Callout</h3><a id="user-content-vendor-specified-url-callout" class="anchor" aria-label="Permalink: Vendor-specified URL Callout" href="#vendor-specified-url-callout"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">RTC supports call-outs to third-party vendors. For example, take VendorFooBar which provides an API service that returns similar interests when provided a given interest (i.e. "baseball" yields ["sports", "apple-pie"]). If VendorFooBar wants publishers to be able to use them for RTC call outs, they simply add their call-out url with built-in macros to the AMP RTC vendor registry. Then publishers specify that they want to call out to VendorFooBar, and supply the value to substitute into the macro. This gives the Vendor complete control over the actual URL, with the Publisher only needing to supply the relevant inputs. See the <a href="#url-macro-substitution">URL Macro Substitution</a> section for details.</p> <p dir="auto">In both cases, the results of these call-outs are passed to the Fast Fetch implementations as part of ad url construction via the <strong><code>getAdUrl</code></strong> method. The ad network Fast Fetch implementation then uses results of these callouts to generate the ad URL. The semantics of how the ad network uses the RTC results to general the ad URL is specific to each individual network's implementation of Fast Fetch, so please refer to network-specific documentation for details.</p> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Design</h2><a id="user-content-design" class="anchor" aria-label="Permalink: Design" href="#design"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Per-Slot RTC Specification</h3><a id="user-content-per-slot-rtc-specification" class="anchor" aria-label="Permalink: Per-Slot RTC Specification" href="#per-slot-rtc-specification"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Publishers may use RTC to send callouts to a maximum of 5 different endpoints. Each <code>amp-ad</code> element that uses RTC must have the <code>rtc-config</code> attribute set with valid JSON.</p> <div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">Example 1: RTC specification on an amp-ad</h4><a id="user-content-example-1-rtc-specification-on-an-amp-ad" class="anchor" aria-label="Permalink: Example 1: RTC specification on an amp-ad" href="#example-1-rtc-specification-on-an-amp-ad"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;amp-ad width=&quot;320&quot; height=&quot;50&quot; type=&quot;network-foo&quot; data-slot=&quot;/1234/5678&quot; rtc-config='{ &quot;vendors&quot;: { &quot;vendorA&quot;: {&quot;SLOT_ID&quot;: &quot;1&quot;}, &quot;vendorB&quot;: {&quot;PAGE_ID&quot;: &quot;2&quot;}, &quot;vendorC&quot;: {&quot;SLOT_W&quot;: &quot;320&quot;, &quot;SLOT_H&quot;: &quot;50&quot;} }, &quot;urls&quot;: [ &quot;https://www.AmpPublisher.biz/targetingA&quot;, &quot;https://www.AmpPublisher.biz/targetingB&quot; ], &quot;timeoutMillis&quot;: 750}' &gt; &lt;/amp-ad&gt;"><pre><span class="pl-kos">&lt;</span><span class="pl-ent">amp-ad</span> <span class="pl-c1">width</span>="<span class="pl-s">320</span>" <span class="pl-c1">height</span>="<span class="pl-s">50</span>" <span class="pl-c1">type</span>="<span class="pl-s">network-foo</span>" <span class="pl-c1">data-slot</span>="<span class="pl-s">/1234/5678</span>" <span class="pl-c1">rtc-config</span>='<span class="pl-s">{</span> <span class="pl-s"> "vendors": {</span> <span class="pl-s"> "vendorA": {"SLOT_ID": "1"},</span> <span class="pl-s"> "vendorB": {"PAGE_ID": "2"},</span> <span class="pl-s"> "vendorC": {"SLOT_W": "320", "SLOT_H": "50"}</span> <span class="pl-s"> },</span> <span class="pl-s"> "urls": [</span> <span class="pl-s"> "https://www.AmpPublisher.biz/targetingA",</span> <span class="pl-s"> "https://www.AmpPublisher.biz/targetingB"</span> <span class="pl-s"> ],</span> <span class="pl-s"> "timeoutMillis": 750}</span>' <span class="pl-kos">&gt;</span> <span class="pl-kos">&lt;/</span><span class="pl-ent">amp-ad</span><span class="pl-kos">&gt;</span></pre></div> <p dir="auto">The value of <code>rtc-config</code> must conform to the following specification:</p> <div class="highlight highlight-source-json notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="{ &quot;vendors&quot;: { &quot;vendor1&quot;: { &quot;MACRO_1&quot;: &quot;MACRO_VALUE_1&quot;, &quot;MACRO_2&quot;: &quot;MACRO_VALUE_2&quot; }, &quot;vendor2&quot;: { &quot;MACRO_1&quot;: &quot;MACRO_VALUE_1&quot;, &quot;MACRO_2&quot;: &quot;MACRO_VALUE_2&quot; } }, &quot;urls&quot;: [ &quot;https://www.exampleA.com/endpoint&quot;, { &quot;url&quot;: &quot;https://www.exampleB.com/endpoint&quot;, &quot;errorReportingUrl&quot;: &quot;https://www.exampleB.com/endpoint?e=ERROR_TYPE&amp;h=HREF&quot; } ], &quot;timeoutMillis&quot;: 500 }"><pre>{ <span class="pl-ent">"vendors"</span>: { <span class="pl-ent">"vendor1"</span>: { <span class="pl-ent">"MACRO_1"</span>: <span class="pl-s"><span class="pl-pds">"</span>MACRO_VALUE_1<span class="pl-pds">"</span></span>, <span class="pl-ent">"MACRO_2"</span>: <span class="pl-s"><span class="pl-pds">"</span>MACRO_VALUE_2<span class="pl-pds">"</span></span> }, <span class="pl-ent">"vendor2"</span>: { <span class="pl-ent">"MACRO_1"</span>: <span class="pl-s"><span class="pl-pds">"</span>MACRO_VALUE_1<span class="pl-pds">"</span></span>, <span class="pl-ent">"MACRO_2"</span>: <span class="pl-s"><span class="pl-pds">"</span>MACRO_VALUE_2<span class="pl-pds">"</span></span> } }, <span class="pl-ent">"urls"</span>: [ <span class="pl-s"><span class="pl-pds">"</span>https://www.exampleA.com/endpoint<span class="pl-pds">"</span></span>, { <span class="pl-ent">"url"</span>: <span class="pl-s"><span class="pl-pds">"</span>https://www.exampleB.com/endpoint<span class="pl-pds">"</span></span>, <span class="pl-ent">"errorReportingUrl"</span>: <span class="pl-s"><span class="pl-pds">"</span>https://www.exampleB.com/endpoint?e=ERROR_TYPE&amp;h=HREF<span class="pl-pds">"</span></span> } ], <span class="pl-ent">"timeoutMillis"</span>: <span class="pl-c1">500</span> }</pre></div> <ul dir="auto"> <li><code>vendors</code> <ul dir="auto"> <li>Optional parameter</li> <li>Type: Object <ul dir="auto"> <li>Key is the name of the vendor to use. <ul dir="auto"> <li>Vendor to use must appear as a key in <a href="https://github.com/ampproject/amphtml/blob/main/src/service/real-time-config/callout-vendors.js">callout-vendors.js</a></li> </ul> </li> <li>Value is a mapping of macros to values.</li> </ul> </li> <li>Macros for a given vendor URL are specified by that particular vendor. <ul dir="auto"> <li>For example, in the Example 1 above, VendorA has specified the macro SLOT_ID in their callout URL (see <a href="#vendor-url-specification">Vendor URL Specification</a>). The RTC config specifies the value "1" to substitute for SLOT_ID in the callout URL. You may also set the value of a macro as a JSON object or array. This JSON object will be stringified automatically prior to replacement in the URL.</li> <li>Vendors can use the same macros as other vendors.</li> </ul> </li> </ul> </li> <li><code>urls</code> <ul dir="auto"> <li>Optional parameter</li> <li>Type: Array of strings or objects.</li> <li>Each value in the array must be a valid RTC endpoint URL, or an object that contains a <code>url</code> and an <code>errorReportingUrl</code> as URL strings. Note that all URL strings must be secure (i.e. start with HTTPS). The array can be a mix of both of these types, as seen in the example above. In the case that an object is specified, the <code>url</code> within this object is treated equivalently as if it had been specified directly within the array, and errors from callouts to that URL are sent to its corresponding <strong>errorReportingUrl</strong>. The URLs specified here are the "custom URLs" mentioned above and throughout this document. <ul dir="auto"> <li>See <a href="#rtc-callout-endpoint-and-response-specification">RTC Callout Endpoint and Response Specification</a> section below on all requirements for endpoint.</li> <li>See <a href="#rtc-error-pingback">RTC Error Pingback</a> section below for information on how errorReportingUrl is used to send sampled RTC errors, and how to specify an errorReportingUrl.</li> </ul> </li> </ul> </li> <li><code>timeoutMillis</code> <ul dir="auto"> <li>Optional parameter</li> <li>Type: integer</li> <li>Value in milliseconds for timeout to use for each individual RTC callout. Must be less than default value of 1000ms, and greater than 0.</li> </ul> </li> </ul> <p dir="auto">While all three parameters of rtc-config are optional, either "vendors" or "urls" <em>must be specified</em> for RTC to occur. Both may be specified simultaneously. If neither "vendors" nor "urls" are specified, there are no endpoints to callout to and RTC is aborted. An error will be logged to the console.</p> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Vendor URL Specification</h3><a id="user-content-vendor-url-specification" class="anchor" aria-label="Permalink: Vendor URL Specification" href="#vendor-url-specification"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">To spare publishers the details of having to construct URLs for external vendors, vendors may register a URL with macros in a central file called <a href="https://github.com/ampproject/amphtml/blob/main/src/service/real-time-config/callout-vendors.js">callout-vendors.js</a>, which maps unique vendor names to an object which includes a URL and a list of allowed macros that can be substituted into <code>url</code>. Vendors may include these macros in their URLs, which publishers can then specify the value for. Additionally, vendors may specify an <code>errorReportingUrl</code>. This errorReportingUrl will be sent 1% sampled-per-page errors from callouts to their RTC endpoint. For instance:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="/** amp-a4a/0.1/callout-vendors.js */ vendors: { &quot;vendor1&quot;: { &quot;url&quot;: &quot;https://vendor1.com/slot_id=SLOT_ID&quot;, &quot;macros&quot;: ['SLOT_ID'], &quot;errorReportingUrl&quot;: &quot;https://vendor1.com/e=ERROR_TYPE&amp;h=HREF&quot;, } };"><pre lang="text" class="notranslate"><code>/** amp-a4a/0.1/callout-vendors.js */ vendors: { "vendor1": { "url": "https://vendor1.com/slot_id=SLOT_ID", "macros": ['SLOT_ID'], "errorReportingUrl": "https://vendor1.com/e=ERROR_TYPE&amp;h=HREF", } }; </code></pre></div> <p dir="auto">The only valid strings that can be replaced for a given URL are specified by the <code>macros</code> array. In the above example, the only valid macro to replace in <code>https://vendor1.com/slot_id=SLOT_ID</code> is <code>"SLOT_ID"</code>.</p> <p dir="auto">The <code>macros</code> attribute is optional, i.e. a vendor could specify a URL that has no macros to substitute in.</p> <p dir="auto">Additionally, macros can be substituted in by the Fast Fetch implementation itself. The URL for a vendor will be expanded with the correct macro values prior to callout. See <a href="#url-macro-substitution">URL Macro Substitution</a> section below for detailed explanation and example.</p> <p dir="auto">The <code>errorReportingUrl</code> property is optional. The only available macros are ERROR_TYPE and HREF. See <a href="#rtc-error-pingback">RTC Error Pingback</a> section below for more information on how error reporting works.</p> <div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">Currently Supported Vendors</h4><a id="user-content-currently-supported-vendors" class="anchor" aria-label="Permalink: Currently Supported Vendors" href="#currently-supported-vendors"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <ul dir="auto"> <li>Admax</li> <li>Adpushup</li> <li>AppNexus PSP</li> <li>APS</li> <li>Automatad</li> <li>Andbeyond</li> <li>Browsi</li> <li>Criteo</li> <li>Denakop</li> <li>FLUX</li> <li>Freestar</li> <li>Future Plc</li> <li>Galaxie Media</li> <li>Highfivve</li> <li>Hubvisor</li> <li><a href="https://www.improvedigital.com" rel="nofollow">Improve Digital</a></li> <li>IndexExchange</li> <li>Kargo</li> <li>Lotame</li> <li>Media.net</li> <li>Mediasquare</li> <li>Navegg</li> <li>NewsPassID</li> <li>Nexx360.io</li> <li>OpenX</li> <li>PubMatic OpenWrap</li> <li><a href="https://www.pubwise.io" rel="nofollow">PubWise</a></li> <li>Purch</li> <li>RichAudience</li> <li>Rubicon</li> <li>Salesforce</li> <li><a href="https://www.snigel.com" rel="nofollow">Snigel</a></li> <li>Sonobi</li> <li>T13</li> <li>Tail</li> <li>The Ozone Project</li> <li>Yieldbot</li> <li>Yieldlab</li> </ul> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">RTC Callout Request Specification</h3><a id="user-content-rtc-callout-request-specification" class="anchor" aria-label="Permalink: RTC Callout Request Specification" href="#rtc-callout-request-specification"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">RTC callout requests are sent from the AMP runtime with the following headers:</p> <ul dir="auto"> <li>Accept: application/JSON</li> <li>Origin: Whatever the origin of the page is.</li> <li>Referer: Referer URL</li> <li>User-Agent: Standard user-agent information</li> </ul> <p dir="auto">Additionally, query string parameters are optionally sent as per the specification of the URL.</p> <p dir="auto">RTC requests are sent using the <a href="https://github.com/ampproject/amphtml/blob/main/src/service/xhr-impl.js#L213">fetchJson method defined in xhr-impl.js.</a> For RTC, in practice this is a GET request.</p> <p dir="auto">RTC requests are only sent to HTTPS endpoints.</p> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">RTC Callout Endpoint and Response Specification</h3><a id="user-content-rtc-callout-endpoint-and-response-specification" class="anchor" aria-label="Permalink: RTC Callout Endpoint and Response Specification" href="#rtc-callout-endpoint-and-response-specification"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">The RTC endpoint must respond to the RTC GET request with a valid JSON object of targeting information to insert into the ad request URL. Redirects are not allowed, and if the endpoint attempts to redirect, the RTC will be abandoned. Special care should be made to respond to these requests as quickly as possible, as there is a 1 second default timeout imposed by RTC, and publishers may optionally shorten this timeout. Responses that return after the timeout will be dropped.</p> <p dir="auto">Responses from one RTC callout do not affect any of the other RTC callouts. All requests are independent of each other.</p> <p dir="auto">The RTC callout endpoint must use HTTPS. HTTP requests are forbidden.</p> <p dir="auto">The RTC Response to a GET request must meet the following requirements:</p> <ul dir="auto"> <li>Status Code = 200</li> <li>See <a href="https://github.com/ampproject/amphtml/blob/main/docs/spec/amp-cors-requests.md#ensuring-secure-responses">here for Required Headers</a> and note that Access-Control-Allow-Credentials: true must be present for cookies to be included in the request.</li> <li>Body of response is a JSON object of targeting information such as: <ul dir="auto"> <li><strong><code>{"targeting": {"sport":["rugby","cricket"]}}</code></strong></li> <li>The response body must be JSON, but the actual structure of that data need not match the structure here. Refer to Fast Fetch Network specific documentation for the required spec. (for example, if using DoubleClick, refer to DoubleClick docs).</li> </ul> </li> </ul> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">RTC Error Pingback</h3><a id="user-content-rtc-error-pingback" class="anchor" aria-label="Permalink: RTC Error Pingback" href="#rtc-error-pingback"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">RTC supports sending a 1% per-page sampling of RTC errors to specified errorReportingUrl's. (I.e. 1% of pages will send RTC error pingbacks for all RTC errors that occur on that page). For any given RTC callout URL, a corresponding errorReportingUrl may be specified, which will receive pings for, and only for, errors that resulted from the associated RTC callout. For example, you can not specify one errorReportingUrl that receives batched pings for all RTC callouts from a page. The errorReportingUrl must be a secure URL that uses HTTPS.</p> <p dir="auto">Vendors may specify an errorReportingUrl within their config in callout-vendors.js, e.g.:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="/** amp-a4a/0.1/callout-vendors.js */ vendors: { &quot;vendor1&quot;: { &quot;url&quot;: &quot;https://vendor1.com/slot_id=SLOT_ID&quot;, &quot;macros&quot;: ['SLOT_ID'], &quot;errorReportingUrl&quot;: &quot;https://vendor1.com/e=ERROR_TYPE&amp;h=HREF&quot;, } };"><pre lang="text" class="notranslate"><code>/** amp-a4a/0.1/callout-vendors.js */ vendors: { "vendor1": { "url": "https://vendor1.com/slot_id=SLOT_ID", "macros": ['SLOT_ID'], "errorReportingUrl": "https://vendor1.com/e=ERROR_TYPE&amp;h=HREF", } }; </code></pre></div> <p dir="auto">For custom URLs specified by a publisher directly on the RTC Config, they specify the errorReportingUrl by setting values in the "url" array as an object, instead of a string, e.g.:</p> <div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;amp-ad width=&quot;320&quot; height=&quot;50&quot; type=&quot;network-foo&quot; data-slot=&quot;/1234/5678&quot; rtc-config='{ &quot;vendors&quot;: { &quot;vendorA&quot;: {&quot;SLOT_ID&quot;: &quot;1&quot;}, }, &quot;urls&quot;: [ &quot;https://www.AmpPublisher.biz/targetingA&quot;, {&quot;url&quot;: &quot;https://www.AmpPublisher.biz/targetingB&quot;, &quot;errorReportingUrl&quot;: &quot;https://www.AmpPublisher.biz?e=ERROR_TYPE&amp;h=HREF&quot;} ], &quot;timeoutMillis&quot;: 750}' &gt; &lt;/amp-ad&gt;"><pre><span class="pl-kos">&lt;</span><span class="pl-ent">amp-ad</span> <span class="pl-c1">width</span>="<span class="pl-s">320</span>" <span class="pl-c1">height</span>="<span class="pl-s">50</span>" <span class="pl-c1">type</span>="<span class="pl-s">network-foo</span>" <span class="pl-c1">data-slot</span>="<span class="pl-s">/1234/5678</span>" <span class="pl-c1">rtc-config</span>='<span class="pl-s">{</span> <span class="pl-s"> "vendors": {</span> <span class="pl-s"> "vendorA": {"SLOT_ID": "1"},</span> <span class="pl-s"> },</span> <span class="pl-s"> "urls": [</span> <span class="pl-s"> "https://www.AmpPublisher.biz/targetingA",</span> <span class="pl-s"> {"url": "https://www.AmpPublisher.biz/targetingB",</span> <span class="pl-s"> "errorReportingUrl": "https://www.AmpPublisher.biz?e=ERROR_TYPE&amp;h=HREF"}</span> <span class="pl-s"> ],</span> <span class="pl-s"> "timeoutMillis": 750}</span>' <span class="pl-kos">&gt;</span> <span class="pl-kos">&lt;/</span><span class="pl-ent">amp-ad</span><span class="pl-kos">&gt;</span></pre></div> <p dir="auto">In both cases, the requirements for an errorReportingUrl are the same:</p> <ul dir="auto"> <li>errorReportingUrl must use HTTPS.</li> <li>Response should be an empty 200.</li> <li>errorReportingUrl may utilize two available macros that will be substituted in: <ul dir="auto"> <li><strong>ERROR_TYPE</strong> - Will be sent as an enum value that corresponds to values in <code>RTC_ERROR_ENUM</code> found in <a href="https://github.com/ampproject/amphtml/blob/main/src/service/real-time-config/real-time-config-impl.js">real-time-config-impl.js</a>.</li> <li><strong>HREF</strong> - The actual full URL of the page. Equivalent to historical value of AMP's window.context.location.href.</li> </ul> </li> </ul> <p dir="auto">The error ping will be sent by creating an image pixel in the document. See <code>sendErrorMessage</code> in <a href="https://github.com/ampproject/amphtml/blob/main/src/service/real-time-config/real-time-config-impl.js">real-time-config-impl.js</a> for implementation details.</p> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">AMP Consent Integration</h3><a id="user-content-amp-consent-integration" class="anchor" aria-label="Permalink: AMP Consent Integration" href="#amp-consent-integration"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">The AMP-Consent extension provides publishers the ability to collect and store a user's consent through a UI control, while also providing the ability to block other AMP components based on the user's consent. See <a href="https://github.com/ampproject/amphtml/blob/main/extensions/amp-consent/amp-consent.md">here for documentation</a>.</p> <p dir="auto">Real Time Config supports integration with AMP-Consent. If the AMP-consent response is neither <code>SUFFICIENT</code> nor <code>UNKNOWN_NOT_REQUIRED</code>, then by default all RTC callouts are suppressed. However, you may optionally modify this setting, to allow specific RTC callouts that should be sent regardless of the consent state. A publisher can modify this across all RTC requests for a given ad slot or on a per-RTC-callout basis. A publisher also may either permit all consent states, or only specific consent states, using the RTC Config attribute <code>sendRegardlessOfConsentState</code>.</p> <p dir="auto">The value of <code>sendRegardlessOfConsentState</code> should either be the boolean <code>true</code> or an array of consent policy state strings as defined in src/core/constants/consent-state.js (i.e. use the string keys, like<code>"UNKNOWN"</code> not its corresponding numeric value). In a case where the RTC callout would normally be supressed (for example if the AMP-consent response is <code>UNKNOWN</code>), it will instead be sent if <code>sendRegardlessOfConsentState</code> is set to boolean <code>true</code> or an array of values that contains a match for the AMP-consent state response (e.g. <code>['UNKNOWN']</code>). If set to an array, then only the values in that array (in addition to the defualt values of <code>SUFFICIENT</code> and <code>UNKNOWN_NOT_REQUIRED</code>) are treated as valid.</p> <p dir="auto">The setting of <code>sendRegardlessOfConsentState</code> can either be done once for the entire ad slot by setting it as a top-level attribute on the RTC Config, or be done individually by setting it on any individual callouts as needed. If it is set at both the top-level and per-callout level, then if there is a mismatch, the per-callout level "wins". This is detailed below in the examples.</p> <p dir="auto">Here are various examples of how to do this for any given ad slot:</p> <div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">Allow all RTC callouts for all consent states</h4><a id="user-content-allow-all-rtc-callouts-for-all-consent-states" class="anchor" aria-label="Permalink: Allow all RTC callouts for all consent states" href="#allow-all-rtc-callouts-for-all-consent-states"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;amp-ad width=&quot;320&quot; height=&quot;50&quot; type=&quot;network-foo&quot; data-slot=&quot;/1234/5678&quot; rtc-config='{ &quot;vendors&quot;: { &quot;vendorA&quot;: {&quot;SLOT_ID&quot;: &quot;1&quot;}, &quot;vendorB&quot;: {&quot;PAGE_ID&quot;: &quot;2&quot;}, &quot;vendorC&quot;: {&quot;SLOT_W&quot;: &quot;320&quot;, &quot;SLOT_H&quot;: &quot;50&quot;} }, &quot;urls&quot;: [ &quot;https://www.AmpPublisher.biz/targetingA&quot;, &quot;https://www.AmpPublisher.biz/targetingB&quot; ], &quot;sendRegardlessOfConsentState&quot;: true}' &gt; &lt;/amp-ad&gt;"><pre><span class="pl-kos">&lt;</span><span class="pl-ent">amp-ad</span> <span class="pl-c1">width</span>="<span class="pl-s">320</span>" <span class="pl-c1">height</span>="<span class="pl-s">50</span>" <span class="pl-c1">type</span>="<span class="pl-s">network-foo</span>" <span class="pl-c1">data-slot</span>="<span class="pl-s">/1234/5678</span>" <span class="pl-c1">rtc-config</span>='<span class="pl-s">{</span> <span class="pl-s"> "vendors": {</span> <span class="pl-s"> "vendorA": {"SLOT_ID": "1"},</span> <span class="pl-s"> "vendorB": {"PAGE_ID": "2"},</span> <span class="pl-s"> "vendorC": {"SLOT_W": "320", "SLOT_H": "50"}</span> <span class="pl-s"> },</span> <span class="pl-s"> "urls": [</span> <span class="pl-s"> "https://www.AmpPublisher.biz/targetingA",</span> <span class="pl-s"> "https://www.AmpPublisher.biz/targetingB"</span> <span class="pl-s"> ],</span> <span class="pl-s"> "sendRegardlessOfConsentState": true}</span>' <span class="pl-kos">&gt;</span> <span class="pl-kos">&lt;/</span><span class="pl-ent">amp-ad</span><span class="pl-kos">&gt;</span></pre></div> <p dir="auto">By setting <code>sendRegardlessOfConsentState</code> at top-level to <code>true</code>, this indicates that for any consent state, all of the callouts in this RTC configuration should still be sent.</p> <div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">Allow all RTC callouts for only certain consent states</h4><a id="user-content-allow-all-rtc-callouts-for-only-certain-consent-states" class="anchor" aria-label="Permalink: Allow all RTC callouts for only certain consent states" href="#allow-all-rtc-callouts-for-only-certain-consent-states"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;amp-ad width=&quot;320&quot; height=&quot;50&quot; type=&quot;network-foo&quot; data-slot=&quot;/1234/5678&quot; rtc-config='{ &quot;vendors&quot;: { &quot;vendorA&quot;: {&quot;SLOT_ID&quot;: &quot;1&quot;}, &quot;vendorB&quot;: {&quot;PAGE_ID&quot;: &quot;2&quot;}, &quot;vendorC&quot;: {&quot;SLOT_W&quot;: &quot;320&quot;, &quot;SLOT_H&quot;: &quot;50&quot;} }, &quot;urls&quot;: [ &quot;https://www.AmpPublisher.biz/targetingA&quot;, &quot;https://www.AmpPublisher.biz/targetingB&quot; ], &quot;sendRegardlessOfConsentState&quot;: [&quot;UNKNOWN&quot;]}' &gt; &lt;/amp-ad&gt;"><pre><span class="pl-kos">&lt;</span><span class="pl-ent">amp-ad</span> <span class="pl-c1">width</span>="<span class="pl-s">320</span>" <span class="pl-c1">height</span>="<span class="pl-s">50</span>" <span class="pl-c1">type</span>="<span class="pl-s">network-foo</span>" <span class="pl-c1">data-slot</span>="<span class="pl-s">/1234/5678</span>" <span class="pl-c1">rtc-config</span>='<span class="pl-s">{</span> <span class="pl-s"> "vendors": {</span> <span class="pl-s"> "vendorA": {"SLOT_ID": "1"},</span> <span class="pl-s"> "vendorB": {"PAGE_ID": "2"},</span> <span class="pl-s"> "vendorC": {"SLOT_W": "320", "SLOT_H": "50"}</span> <span class="pl-s"> },</span> <span class="pl-s"> "urls": [</span> <span class="pl-s"> "https://www.AmpPublisher.biz/targetingA",</span> <span class="pl-s"> "https://www.AmpPublisher.biz/targetingB"</span> <span class="pl-s"> ],</span> <span class="pl-s"> "sendRegardlessOfConsentState": ["UNKNOWN"]}</span>' <span class="pl-kos">&gt;</span> <span class="pl-kos">&lt;/</span><span class="pl-ent">amp-ad</span><span class="pl-kos">&gt;</span></pre></div> <p dir="auto">By setting <code>sendRegardlessOfConsentState</code> to an array, this indicates that only when the page consent state matches any of the consent states in the array (in this case only <code>UNKNOWN</code> in addition to the default states <code>SUFFICIENT</code> and <code>UNKNOWN_NOT_REQUIRED</code>) should all of the RTC callouts still be sent. For instance, if the page state is <code>INSUFFICIENT</code>, then none of the callout specified above will be sent. If the page state is <code>UNKNOWN</code>, then all of the callouts will be sent.</p> <div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">Allow some RTC callouts in the "url" array</h4><a id="user-content-allow-some-rtc-callouts-in-the-url-array" class="anchor" aria-label="Permalink: Allow some RTC callouts in the &quot;url&quot; array" href="#allow-some-rtc-callouts-in-the-url-array"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;amp-ad width=&quot;320&quot; height=&quot;50&quot; type=&quot;network-foo&quot; data-slot=&quot;/1234/5678&quot; rtc-config='{ &quot;vendors&quot;: { &quot;vendorA&quot;: {&quot;SLOT_ID&quot;: &quot;1&quot;}, &quot;vendorB&quot;: {&quot;PAGE_ID&quot;: &quot;2&quot;}, &quot;vendorC&quot;: {&quot;SLOT_W&quot;: &quot;320&quot;, &quot;SLOT_H&quot;: &quot;50&quot;} }, &quot;urls&quot;: [ {&quot;url&quot;: &quot;https://www.AmpPublisher.biz/targetingA&quot;, &quot;sendRegardlessOfConsentState&quot;: true}, &quot;https://www.AmpPublisher.biz/targetingB&quot; ]}' &gt; &lt;/amp-ad&gt;"><pre><span class="pl-kos">&lt;</span><span class="pl-ent">amp-ad</span> <span class="pl-c1">width</span>="<span class="pl-s">320</span>" <span class="pl-c1">height</span>="<span class="pl-s">50</span>" <span class="pl-c1">type</span>="<span class="pl-s">network-foo</span>" <span class="pl-c1">data-slot</span>="<span class="pl-s">/1234/5678</span>" <span class="pl-c1">rtc-config</span>='<span class="pl-s">{</span> <span class="pl-s"> "vendors": {</span> <span class="pl-s"> "vendorA": {"SLOT_ID": "1"},</span> <span class="pl-s"> "vendorB": {"PAGE_ID": "2"},</span> <span class="pl-s"> "vendorC": {"SLOT_W": "320", "SLOT_H": "50"}</span> <span class="pl-s"> },</span> <span class="pl-s"> "urls": [</span> <span class="pl-s"> {"url": "https://www.AmpPublisher.biz/targetingA",</span> <span class="pl-s"> "sendRegardlessOfConsentState": true},</span> <span class="pl-s"> "https://www.AmpPublisher.biz/targetingB"</span> <span class="pl-s"> ]}</span>' <span class="pl-kos">&gt;</span> <span class="pl-kos">&lt;/</span><span class="pl-ent">amp-ad</span><span class="pl-kos">&gt;</span></pre></div> <p dir="auto">In this example, <code>sendRegardlessOfConsentState</code> is only set for one specific URL, the first URL in the array "urls". Take the case when the page state is <code>UNKNOWN</code>. In that case, the only RTC callout that would be sent is the one to <code>https://www.AmpPublisher.biz/targetingA</code>.</p> <p dir="auto">Is is also possible to set <code>sendRegardlessOfConsentState</code> here to an array as well, such as:</p> <div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;amp-ad width=&quot;320&quot; height=&quot;50&quot; type=&quot;network-foo&quot; data-slot=&quot;/1234/5678&quot; rtc-config='{ &quot;vendors&quot;: { &quot;vendorA&quot;: {&quot;SLOT_ID&quot;: &quot;1&quot;}, &quot;vendorB&quot;: {&quot;PAGE_ID&quot;: &quot;2&quot;}, &quot;vendorC&quot;: {&quot;SLOT_W&quot;: &quot;320&quot;, &quot;SLOT_H&quot;: &quot;50&quot;} }, &quot;urls&quot;: [ {&quot;url&quot;: &quot;https://www.AmpPublisher.biz/targetingA&quot;, &quot;sendRegardlessOfConsentState&quot;: [&quot;UNKNOWN&quot;, &quot;INSUFFICIENT&quot;]}, &quot;https://www.AmpPublisher.biz/targetingB&quot; ]}' &gt; &lt;/amp-ad&gt;"><pre><span class="pl-kos">&lt;</span><span class="pl-ent">amp-ad</span> <span class="pl-c1">width</span>="<span class="pl-s">320</span>" <span class="pl-c1">height</span>="<span class="pl-s">50</span>" <span class="pl-c1">type</span>="<span class="pl-s">network-foo</span>" <span class="pl-c1">data-slot</span>="<span class="pl-s">/1234/5678</span>" <span class="pl-c1">rtc-config</span>='<span class="pl-s">{</span> <span class="pl-s"> "vendors": {</span> <span class="pl-s"> "vendorA": {"SLOT_ID": "1"},</span> <span class="pl-s"> "vendorB": {"PAGE_ID": "2"},</span> <span class="pl-s"> "vendorC": {"SLOT_W": "320", "SLOT_H": "50"}</span> <span class="pl-s"> },</span> <span class="pl-s"> "urls": [</span> <span class="pl-s"> {"url": "https://www.AmpPublisher.biz/targetingA",</span> <span class="pl-s"> "sendRegardlessOfConsentState": ["UNKNOWN", "INSUFFICIENT"]},</span> <span class="pl-s"> "https://www.AmpPublisher.biz/targetingB"</span> <span class="pl-s"> ]}</span>' <span class="pl-kos">&gt;</span> <span class="pl-kos">&lt;/</span><span class="pl-ent">amp-ad</span><span class="pl-kos">&gt;</span></pre></div> <div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">Allow some RTC callouts in the "vendors" object</h4><a id="user-content-allow-some-rtc-callouts-in-the-vendors-object" class="anchor" aria-label="Permalink: Allow some RTC callouts in the &quot;vendors&quot; object" href="#allow-some-rtc-callouts-in-the-vendors-object"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;amp-ad width=&quot;320&quot; height=&quot;50&quot; type=&quot;network-foo&quot; data-slot=&quot;/1234/5678&quot; rtc-config='{ &quot;vendors&quot;: { &quot;vendorA&quot;: {&quot;macros&quot; {&quot;SLOT_ID&quot;: &quot;1&quot;}, &quot;sendRegardlessOfConsentState&quot;: [&quot;UNKNOWN&quot;]}, &quot;vendorB&quot;: {&quot;PAGE_ID&quot;: &quot;2&quot;}, &quot;vendorC&quot;: {&quot;SLOT_W&quot;: &quot;320&quot;, &quot;SLOT_H&quot;: &quot;50&quot;} }, &quot;urls&quot;: [ &quot;https://www.AmpPublisher.biz/targetingA&quot;, &quot;https://www.AmpPublisher.biz/targetingB&quot; ]}' &gt; &lt;/amp-ad&gt;"><pre><span class="pl-kos">&lt;</span><span class="pl-ent">amp-ad</span> <span class="pl-c1">width</span>="<span class="pl-s">320</span>" <span class="pl-c1">height</span>="<span class="pl-s">50</span>" <span class="pl-c1">type</span>="<span class="pl-s">network-foo</span>" <span class="pl-c1">data-slot</span>="<span class="pl-s">/1234/5678</span>" <span class="pl-c1">rtc-config</span>='<span class="pl-s">{</span> <span class="pl-s"> "vendors": {</span> <span class="pl-s"> "vendorA": {"macros" {"SLOT_ID": "1"},</span> <span class="pl-s"> "sendRegardlessOfConsentState": ["UNKNOWN"]},</span> <span class="pl-s"> "vendorB": {"PAGE_ID": "2"},</span> <span class="pl-s"> "vendorC": {"SLOT_W": "320", "SLOT_H": "50"}</span> <span class="pl-s"> },</span> <span class="pl-s"> "urls": [</span> <span class="pl-s"> "https://www.AmpPublisher.biz/targetingA",</span> <span class="pl-s"> "https://www.AmpPublisher.biz/targetingB"</span> <span class="pl-s"> ]}</span>' <span class="pl-kos">&gt;</span> <span class="pl-kos">&lt;/</span><span class="pl-ent">amp-ad</span><span class="pl-kos">&gt;</span></pre></div> <p dir="auto">In this example, <code>sendRegardlessOfConsentState</code> is only set for one specific URL, the first vendor in the "vendors" object. Take the case when the page state is <code>UNKNOWN</code>. In that case, the only RTC callout that would be sent is the one to vendorA.</p> <div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">Mixture of settings</h4><a id="user-content-mixture-of-settings" class="anchor" aria-label="Permalink: Mixture of settings" href="#mixture-of-settings"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;amp-ad width=&quot;320&quot; height=&quot;50&quot; type=&quot;network-foo&quot; data-slot=&quot;/1234/5678&quot; rtc-config='{ &quot;vendors&quot;: { &quot;vendorA&quot;: {&quot;macros&quot; {&quot;SLOT_ID&quot;: &quot;1&quot;}, &quot;sendRegardlessOfConsentState&quot;: [&quot;INSUFFICIENT&quot;]}, &quot;vendorB&quot;: {&quot;PAGE_ID&quot;: &quot;2&quot;}, &quot;vendorC&quot;: {&quot;SLOT_W&quot;: &quot;320&quot;, &quot;SLOT_H&quot;: &quot;50&quot;} }, &quot;urls&quot;: [ {&quot;url&quot;: &quot;https://www.AmpPublisher.biz/targetingA&quot;, &quot;sendRegardlessOfConsentState&quot;: [&quot;UNKNOWN&quot;]}, &quot;https://www.AmpPublisher.biz/targetingB&quot; ], &quot;sendRegardlessOfConsentState&quot;: true}' &gt; &lt;/amp-ad&gt;"><pre><span class="pl-kos">&lt;</span><span class="pl-ent">amp-ad</span> <span class="pl-c1">width</span>="<span class="pl-s">320</span>" <span class="pl-c1">height</span>="<span class="pl-s">50</span>" <span class="pl-c1">type</span>="<span class="pl-s">network-foo</span>" <span class="pl-c1">data-slot</span>="<span class="pl-s">/1234/5678</span>" <span class="pl-c1">rtc-config</span>='<span class="pl-s">{</span> <span class="pl-s"> "vendors": {</span> <span class="pl-s"> "vendorA": {"macros" {"SLOT_ID": "1"},</span> <span class="pl-s"> "sendRegardlessOfConsentState": ["INSUFFICIENT"]},</span> <span class="pl-s"> "vendorB": {"PAGE_ID": "2"},</span> <span class="pl-s"> "vendorC": {"SLOT_W": "320", "SLOT_H": "50"}</span> <span class="pl-s"> },</span> <span class="pl-s"> "urls": [</span> <span class="pl-s"> {"url": "https://www.AmpPublisher.biz/targetingA",</span> <span class="pl-s"> "sendRegardlessOfConsentState": ["UNKNOWN"]},</span> <span class="pl-s"> "https://www.AmpPublisher.biz/targetingB"</span> <span class="pl-s"> ],</span> <span class="pl-s"> "sendRegardlessOfConsentState": true}</span>' <span class="pl-kos">&gt;</span> <span class="pl-kos">&lt;/</span><span class="pl-ent">amp-ad</span><span class="pl-kos">&gt;</span></pre></div> <p dir="auto">In this example, we have a mixture of various settings. In addition to all the callouts allowing the default states <code>SUFFICIENT</code> and <code>UNKNOWN_NOT_REQUIRED</code>, VendorA is set to allow page consent-state <code>INSUFFICIENT</code>, the first url in the <code>urls</code> array only state <code>UNKNOWN</code>, and the top-level setting across all the RTC callouts is set to <code>true</code>, indicating that we should send all RTC callouts regardless of consent-state. How do we reconcile these various values? As explained above, in the case where a top-level setting and a per-callout setting disagree, the per-callout setting wins.</p> <p dir="auto">Let's first take an example where the page consent-state is <code>SUFFICIENT</code>. This is a default allowed state, so trivially all the callouts will be sent.</p> <p dir="auto">Next, let's take an example where the page consent-state is <code>UNKNOWN</code>. The callout to vendorA is set to allow consent-state <code>INSUFFICIENT</code>, so it will not be sent. The callouts to vendorB and vendorC do not have individual <code>sendRegardlessOfConsentState</code> settings, so the top-level setting of <code>true</code> applies to them, and they will each be sent. In the <code>urls</code> array, the first URL has an individual setting of <code>UNKNOWN</code>, which is the current state, so it will be sent. Lastly, the final url does not have an individual setting, so the top-level setting of <code>true</code> applies to it, and it will be sent.</p> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Blocking RTC</h3><a id="user-content-blocking-rtc" class="anchor" aria-label="Permalink: Blocking RTC" href="#blocking-rtc"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">The <code>block-rtc</code> provides a way to utilize the <code>&lt;amp-geo&gt;</code> component to detect user's geo location to decide if a RTC callout should be prevented. The value of <code>block-rtc</code> should be a comma delimited string of geo group codes which are defined in <code>&lt;amp-geo&gt;</code> (details <a href="https://github.com/ampproject/amphtml/blob/main/extensions/amp-geo/amp-geo.md">here</a>). If no <code>&lt;amp-geo&gt;</code> element is found or no valid value for this attribute, then the RTC callout will occur as normal.</p> <div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;amp-ad width=&quot;300&quot; height=&quot;200&quot; type=&quot;network-foo&quot; data-slot=&quot;/1234/5678&quot; block-rtc=&quot;geoGroup1,geoGroup2&quot; rtc-config='{ &quot;vendors&quot;: { &quot;vendorA&quot;: {&quot;SLOT_ID&quot;: &quot;1&quot;}, &quot;vendorB&quot;: {&quot;PAGE_ID&quot;: &quot;2&quot;}, &quot;vendorC&quot;: {&quot;SLOT_W&quot;: &quot;320&quot;, &quot;SLOT_H&quot;: &quot;50&quot;} }, &quot;urls&quot;: [ &quot;https://www.AmpPublisher.biz/targetingA&quot;, &quot;https://www.AmpPublisher.biz/targetingB&quot; ], &quot;sendRegardlessOfConsentState&quot;: true}' &gt; &lt;/amp-ad&gt; &lt;amp-geo&gt; &lt;script type=&quot;application/json&quot;&gt; { &quot;ISOCountryGroups&quot;: { &quot;geoGroup1&quot;: [ &quot;preset-eea&quot;, &quot;unknown&quot; ], &quot;geoGroup2&quot;: [ &quot;preset-us-ca&quot; ] } } &lt;/script&gt; &lt;/amp-geo&gt;"><pre><span class="pl-kos">&lt;</span><span class="pl-ent">amp-ad</span> <span class="pl-c1">width</span>="<span class="pl-s">300</span>" <span class="pl-c1">height</span>="<span class="pl-s">200</span>" <span class="pl-c1">type</span>="<span class="pl-s">network-foo</span>" <span class="pl-c1">data-slot</span>="<span class="pl-s">/1234/5678</span>" <span class="pl-c1">block-rtc</span>="<span class="pl-s">geoGroup1,geoGroup2</span>" <span class="pl-c1">rtc-config</span>='<span class="pl-s">{</span> <span class="pl-s"> "vendors": {</span> <span class="pl-s"> "vendorA": {"SLOT_ID": "1"},</span> <span class="pl-s"> "vendorB": {"PAGE_ID": "2"},</span> <span class="pl-s"> "vendorC": {"SLOT_W": "320", "SLOT_H": "50"}</span> <span class="pl-s"> },</span> <span class="pl-s"> "urls": [</span> <span class="pl-s"> "https://www.AmpPublisher.biz/targetingA",</span> <span class="pl-s"> "https://www.AmpPublisher.biz/targetingB"</span> <span class="pl-s"> ],</span> <span class="pl-s"> "sendRegardlessOfConsentState": true}</span>' <span class="pl-kos">&gt;</span> <span class="pl-kos">&lt;/</span><span class="pl-ent">amp-ad</span><span class="pl-kos">&gt;</span> <span class="pl-kos">&lt;</span><span class="pl-ent">amp-geo</span><span class="pl-kos">&gt;</span> <span class="pl-kos">&lt;</span><span class="pl-ent">script</span> <span class="pl-c1">type</span>="<span class="pl-s">application/json</span>"<span class="pl-kos">&gt;</span> <span class="pl-kos">{</span> <span class="pl-s">"ISOCountryGroups"</span>: <span class="pl-kos">{</span> <span class="pl-s">"geoGroup1"</span>: <span class="pl-kos">[</span> <span class="pl-s">"preset-eea"</span><span class="pl-kos">,</span> <span class="pl-s">"unknown"</span> <span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-s">"geoGroup2"</span>: <span class="pl-kos">[</span> <span class="pl-s">"preset-us-ca"</span> <span class="pl-kos">]</span> <span class="pl-kos">}</span> <span class="pl-kos">}</span> <span class="pl-kos">&lt;/</span><span class="pl-ent">script</span><span class="pl-kos">&gt;</span> <span class="pl-kos">&lt;/</span><span class="pl-ent">amp-geo</span><span class="pl-kos">&gt;</span></pre></div> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">URL Macro Substitution</h3><a id="user-content-url-macro-substitution" class="anchor" aria-label="Permalink: URL Macro Substitution" href="#url-macro-substitution"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">RTC supports macro substitution for building callout URLs. These macros can be specified by vendors, and by Fast Fetch implementations.</p> <div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">Vendor Defined Macros</h4><a id="user-content-vendor-defined-macros" class="anchor" aria-label="Permalink: Vendor Defined Macros" href="#vendor-defined-macros"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">A vendor can specify macros for substitution in their URL. The only requirement to do this is to include text in their URL in <a href="https://github.com/ampproject/amphtml/blob/main/src/service/real-time-config/callout-vendors.js">callout-vendors.js</a> that is intended to be replaced.</p> <p dir="auto"><strong>Example</strong></p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="/** amp-a4a/0.1/callout-vendors.js */ vendors: { &quot;vendor1&quot;: { &quot;url&quot;: &quot;https://vendor1.com/foo?slot_id=SLOT_ID&quot;, &quot;macros&quot;: ['SLOT_ID'] } };"><pre lang="text" class="notranslate"><code>/** amp-a4a/0.1/callout-vendors.js */ vendors: { "vendor1": { "url": "https://vendor1.com/foo?slot_id=SLOT_ID", "macros": ['SLOT_ID'] } }; </code></pre></div> <div class="markdown-heading" dir="auto"><h5 tabindex="-1" class="heading-element" dir="auto">Example 2: Use of Vendor URLs</h5><a id="user-content-example-2-use-of-vendor-urls" class="anchor" aria-label="Permalink: Example 2: Use of Vendor URLs" href="#example-2-use-of-vendor-urls"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">If a publisher wishes to callout to vendor1, then they would specify their RTC config as:</p> <div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;amp-ad width=&quot;320&quot; height=&quot;50&quot; type=&quot;network-foo&quot; data-slot=&quot;/1234/5678&quot; rtc-config='{ &quot;vendors&quot;: { &quot;vendor1&quot;: {&quot;SLOT_ID&quot;: &quot;1234&quot;} } }' &gt; &lt;/amp-ad&gt;"><pre><span class="pl-kos">&lt;</span><span class="pl-ent">amp-ad</span> <span class="pl-c1">width</span>="<span class="pl-s">320</span>" <span class="pl-c1">height</span>="<span class="pl-s">50</span>" <span class="pl-c1">type</span>="<span class="pl-s">network-foo</span>" <span class="pl-c1">data-slot</span>="<span class="pl-s">/1234/5678</span>" <span class="pl-c1">rtc-config</span>='<span class="pl-s">{</span> <span class="pl-s"> "vendors": {</span> <span class="pl-s"> "vendor1": {"SLOT_ID": "1234"}</span> <span class="pl-s"> }</span> <span class="pl-s"> }</span>' <span class="pl-kos">&gt;</span> <span class="pl-kos">&lt;/</span><span class="pl-ent">amp-ad</span><span class="pl-kos">&gt;</span></pre></div> <p dir="auto">The resulting RTC callout URL will then be, after macro expansion:</p> <p dir="auto"><strong><code>https://vendor1.com/foo?slot_id=1234</code></strong></p> <div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">Fast Fetch Implementation Defined Macros</h4><a id="user-content-fast-fetch-implementation-defined-macros" class="anchor" aria-label="Permalink: Fast Fetch Implementation Defined Macros" href="#fast-fetch-implementation-defined-macros"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">In addition to vendor-defined macros, with publishers specifying the values for substitution, there is also the ability to utilize macros defined by the Fast Fetch implementation. For example, imagine if there is a property, <strong>fooProp,</strong> of the element <strong>fooEl</strong> that is only calculated at runtime. A Fast Fetch network that wants to support optionally adding the value of fooProp to RTC callout URLs that it sends can do so by overriding the method <a href="https://github.com/ampproject/amphtml/blob/main/extensions/amp-a4a/0.1/amp-a4a.js">getCustomRealTimeConfigMacros on AmpA4a </a>in their Fast Fetch implementation. The method should return a mapping of macros to values or functions that resolve to a value.</p> <div class="markdown-heading" dir="auto"><h5 tabindex="-1" class="heading-element" dir="auto">Example 3: Fast Fetch implementation defined macros</h5><a id="user-content-example-3-fast-fetch-implementation-defined-macros" class="anchor" aria-label="Permalink: Example 3: Fast Fetch implementation defined macros" href="#example-3-fast-fetch-implementation-defined-macros"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">For example, Ad Network AmpAdCom overrides the property in their Fast Fetch Implementation:</p> <div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="/** amp-ad-network-ampadcom-impl.js */ export class AmpAdNetworkAmpAdComImpl extends AmpA4A { ... /** @override */ getCustomRealTimeConfigMacros() { return { ‘FOO_PROP’: getElementById(‘fooEl’).getAttribute(‘fooProp’), ‘OTHER_PROP’: ‘staticValue’ } }"><pre><span class="pl-c">/** amp-ad-network-ampadcom-impl.js */</span> <span class="pl-k">export</span> <span class="pl-k">class</span> <span class="pl-v">AmpAdNetworkAmpAdComImpl</span> <span class="pl-k">extends</span> <span class="pl-v">AmpA4A</span> <span class="pl-kos">{</span> ... <span class="pl-c">/** <span class="pl-k">@override</span> */</span> <span class="pl-en">getCustomRealTimeConfigMacros</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> <span class="pl-k">return</span> <span class="pl-kos">{</span> <span class="pl-c1">‘FOO_PROP’</span>: <span class="pl-en">getElementById</span><span class="pl-kos">(</span><span class="pl-s1">‘fooEl’</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">getAttribute</span><span class="pl-kos">(</span><span class="pl-s1">‘fooProp’</span><span class="pl-kos">)</span><span class="pl-kos">,</span> <span class="pl-c1">‘OTHER_PROP’</span>: <span class="pl-s1">‘staticValue’</span> <span class="pl-kos">}</span> <span class="pl-kos">}</span><span class="pl-kos"></span></pre></div> <p dir="auto">Then, publishers and vendors alike would be able to specify the macro FOO_PROP in their URL, and the value would be substituted in at runtime by the Fast Fetch implementation.</p> <div class="markdown-heading" dir="auto"><h5 tabindex="-1" class="heading-element" dir="auto">Vendor Macro Substitution with Fast Fetch Network Macro Substitution</h5><a id="user-content-vendor-macro-substitution-with-fast-fetch-network-macro-substitution" class="anchor" aria-label="Permalink: Vendor Macro Substitution with Fast Fetch Network Macro Substitution" href="#vendor-macro-substitution-with-fast-fetch-network-macro-substitution"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">It is possible for a vendor to specify macros in their URL into which the Fast Fetch implementation will substitute values, in addition to their own custom macros that the publisher may specify in the rtc-config. Take the following example:</p> <div class="markdown-heading" dir="auto"><h6 tabindex="-1" class="heading-element" dir="auto">Example 4</h6><a id="user-content-example-4" class="anchor" aria-label="Permalink: Example 4" href="#example-4"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Vendor1 wants to allow publishers to substitute in the value of the slot_id, and allow the Fast Fetch network implementation to substitute in the start time. Thus, they define their URL in <a href="https://github.com/ampproject/amphtml/blob/main/src/service/real-time-config/callout-vendors.js">callout-vendors.js</a> as follows. Note, the vendor only lists SLOT_ID in the macros array, even though SLOT_ID and START are both macros in their URL. The macros array is a list of macros that can be utilized by the publisher. Fast Fetch will always attempt to substitute in network-defined macros, regardless of whether they are defined in the macros array.</p> <div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="/** amp-a4a/0.1/callout-vendors.js */ vendors: { &quot;vendor1&quot;: { &quot;url&quot;: &quot;https://vendor1.com/slot_id=SLOT_ID&amp;start_time=START&quot;, &quot;macros&quot;: ['SLOT_ID'] } };"><pre><span class="pl-c">/** amp-a4a/0.1/callout-vendors.js */</span> vendors: <span class="pl-kos">{</span> <span class="pl-s">"vendor1"</span>: <span class="pl-kos">{</span> <span class="pl-s">"url"</span>: <span class="pl-s">"https://vendor1.com/slot_id=SLOT_ID&amp;start_time=START"</span><span class="pl-kos">,</span> <span class="pl-s">"macros"</span>: <span class="pl-kos">[</span><span class="pl-s">'SLOT_ID'</span><span class="pl-kos">]</span> <span class="pl-kos">}</span> <span class="pl-kos">}</span><span class="pl-kos">;</span></pre></div> <p dir="auto">The Fast Fetch implementation has overridden <strong>getCustomRealTimeConfigMacros</strong>, and supports the macro 'START', as seen here:</p> <div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="/** amp-ad-network-ampadcom-impl.js */ export class AmpAdNetworkAmpAdComImpl extends AmpA4A { ... /** @override */ getCustomRealTimeConfigMacros() { return { 'START': Date.now() } }"><pre><span class="pl-c">/** amp-ad-network-ampadcom-impl.js */</span> <span class="pl-k">export</span> <span class="pl-k">class</span> <span class="pl-v">AmpAdNetworkAmpAdComImpl</span> <span class="pl-k">extends</span> <span class="pl-v">AmpA4A</span> <span class="pl-kos">{</span> ... <span class="pl-c">/** <span class="pl-k">@override</span> */</span> <span class="pl-en">getCustomRealTimeConfigMacros</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> <span class="pl-k">return</span> <span class="pl-kos">{</span> <span class="pl-s">'START'</span>: <span class="pl-v">Date</span><span class="pl-kos">.</span><span class="pl-en">now</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">}</span> <span class="pl-kos">}</span><span class="pl-kos"></span></pre></div> <p dir="auto">Finally, a publisher who wishes to use Vendor1 with AmpAdCom's Fast Fetch implementation defines their rtc-config as:</p> <div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;!-- ampPublisher.biz/some/example/page.html --&gt; &lt;amp-ad width=&quot;320&quot; height=&quot;50&quot; type=&quot;network-foo&quot; data-slot=&quot;/1234/5678&quot; rtc-config='{ &quot;vendors&quot;: { &quot;vendor1&quot;: {&quot;SLOT_ID&quot;: &quot;1234&quot;} } }' &gt; &lt;/amp-ad&gt;"><pre><span class="pl-c">&lt;!-- ampPublisher.biz/some/example/page.html --&gt;</span> <span class="pl-kos">&lt;</span><span class="pl-ent">amp-ad</span> <span class="pl-c1">width</span>="<span class="pl-s">320</span>" <span class="pl-c1">height</span>="<span class="pl-s">50</span>" <span class="pl-c1">type</span>="<span class="pl-s">network-foo</span>" <span class="pl-c1">data-slot</span>="<span class="pl-s">/1234/5678</span>" <span class="pl-c1">rtc-config</span>='<span class="pl-s">{</span> <span class="pl-s"> "vendors": {</span> <span class="pl-s"> "vendor1": {"SLOT_ID": "1234"}</span> <span class="pl-s"> }</span> <span class="pl-s"> }</span>' <span class="pl-kos">&gt;</span> <span class="pl-kos">&lt;/</span><span class="pl-ent">amp-ad</span><span class="pl-kos">&gt;</span></pre></div> <p dir="auto">After URL macro expansion, the resulting URL is then</p> <div class="highlight highlight-source-httpspec notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="https://vendor1.com/slot_id=1234&amp;start_time=1508508227577"><pre><span class="pl-ii">https://vendor1.com/slot_id=1234&amp;start_time=1508508227577</span></pre></div> <div class="markdown-heading" dir="auto"><h5 tabindex="-1" class="heading-element" dir="auto">Conflicting macro substitution</h5><a id="user-content-conflicting-macro-substitution" class="anchor" aria-label="Permalink: Conflicting macro substitution" href="#conflicting-macro-substitution"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">It is possible, but inadvisable, to have a situation where a vendor specifies the same macro as the Fast Fetch network, i.e. in the above example if <strong>getCustomRealTimeConfigMacros</strong> was defined as</p> <div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="/** amp-ad-network-ampadcom-impl.js */ export class AmpAdNetworkAmpAdComImpl extends AmpA4A { ... /** @override */ getCustomRealTimeConfigMacros() { return { 'START': Date.now(), 'SLOT_ID': '5678' } }"><pre><span class="pl-c">/** amp-ad-network-ampadcom-impl.js */</span> <span class="pl-k">export</span> <span class="pl-k">class</span> <span class="pl-v">AmpAdNetworkAmpAdComImpl</span> <span class="pl-k">extends</span> <span class="pl-v">AmpA4A</span> <span class="pl-kos">{</span> ... <span class="pl-c">/** <span class="pl-k">@override</span> */</span> <span class="pl-en">getCustomRealTimeConfigMacros</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> <span class="pl-k">return</span> <span class="pl-kos">{</span> <span class="pl-s">'START'</span>: <span class="pl-v">Date</span><span class="pl-kos">.</span><span class="pl-en">now</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">,</span> <span class="pl-s">'SLOT_ID'</span>: <span class="pl-s">'5678'</span> <span class="pl-kos">}</span> <span class="pl-kos">}</span><span class="pl-kos"></span></pre></div> <p dir="auto">There is a collision in this case, because the Fast Fetch network is specifying a value to substitute for SLOT_ID, but the vendor has declared SLOT_ID as their custom macro, and the publisher is then trying to substitute in '1234' as the value. In a case like this, the Fast Fetch implementation always wins, i.e. the final URL would be:</p> <div class="highlight highlight-source-httpspec notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="https://vendor1.com/slot_id=5678&amp;start_time=1508508227577"><pre><span class="pl-ii">https://vendor1.com/slot_id=5678&amp;start_time=1508508227577</span></pre></div> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">RTC Callout Result Merging</h3><a id="user-content-rtc-callout-result-merging" class="anchor" aria-label="Permalink: RTC Callout Result Merging" href="#rtc-callout-result-merging"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">The merging of the results of the RTC callouts into the ad request URL is determined by the Fast Fetch network implementation, and thus may vary. Please refer to the specific documentation for the Fast Fetch implementation in use, for instance refer to the DoubleClick RTC documentation if using DoubleClick for Fast Fetch.</p> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Error Cases</h3><a id="user-content-error-cases" class="anchor" aria-label="Permalink: Error Cases" href="#error-cases"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Listed below are the most prominent error cases in RTC. For usage of the following error cases, see <a href="https://github.com/ampproject/amphtml/blob/main/src/service/real-time-config/real-time-config-impl.js">real-time-config-impl.js</a></p> <div class="markdown-heading" dir="auto"><h5 tabindex="-1" class="heading-element" dir="auto">Misconfigured RTC Config</h5><a id="user-content-misconfigured-rtc-config" class="anchor" aria-label="Permalink: Misconfigured RTC Config" href="#misconfigured-rtc-config"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">If the RTC config specified by the publisher does not meet the specification defined in this document, an error will be logged to the console, and RTC will be aborted.</p> <div class="markdown-heading" dir="auto"><h5 tabindex="-1" class="heading-element" dir="auto">Bad JSON Response</h5><a id="user-content-bad-json-response" class="anchor" aria-label="Permalink: Bad JSON Response" href="#bad-json-response"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">If the response from an RTC callout is not valid JSON, i.e. JSON.parse fails, the response is dropped and ignored. An error is logged to the console.</p> <div class="markdown-heading" dir="auto"><h5 tabindex="-1" class="heading-element" dir="auto">Duplicate Callout URLs</h5><a id="user-content-duplicate-callout-urls" class="anchor" aria-label="Permalink: Duplicate Callout URLs" href="#duplicate-callout-urls"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">RTC does not allow multiple callouts to identical URLs. Multiple callouts to the same domain are allowed, provided something in the path is different. I.e.</p> <p dir="auto">This is not allowed:</p> <markdown-accessiblity-table><table> <tbody><tr> <td>Callout 1: `<a href="https://www.vendor1.com/foo?slot_id=1234`" rel="nofollow">https://www.vendor1.com/foo?slot_id=1234`</a> <p dir="auto"> Callout 2: `<a href="https://www.vendor1.com/foo?slot_id=1234`" rel="nofollow">https://www.vendor1.com/foo?slot_id=1234`</a> </p></td> </tr> <tr> <td>Not allowed </td> </tr> </tbody></table></markdown-accessiblity-table> <p dir="auto">This is allowed:</p> <markdown-accessiblity-table><table> <tbody><tr> <td>Callout 1: `<a href="https://www.vendor1.com/foo?slot_id=1234`" rel="nofollow">https://www.vendor1.com/foo?slot_id=1234`</a> <p dir="auto"> Callout 2: `<a href="https://www.vendor1.com/foo?slot_id=5678`" rel="nofollow">https://www.vendor1.com/foo?slot_id=5678`</a> </p></td> </tr> <tr> <td>Allowed </td> </tr> </tbody></table></markdown-accessiblity-table> <p dir="auto">In the case that more than one callout is attempted to be sent to the same URL, only one will be sent, and an error will be logged to the console for each subsequent attempt to send a callout to that URL.</p> <div class="markdown-heading" dir="auto"><h5 tabindex="-1" class="heading-element" dir="auto">Insecure URLs</h5><a id="user-content-insecure-urls" class="anchor" aria-label="Permalink: Insecure URLs" href="#insecure-urls"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">All RTC requests must be sent to valid SSL endpoints. An attempt to send a request to a URL that does not start with <code>https://</code> will be dropped. An error will be logged to the console.</p> <div class="markdown-heading" dir="auto"><h5 tabindex="-1" class="heading-element" dir="auto">Maximum Callouts Exceeded</h5><a id="user-content-maximum-callouts-exceeded" class="anchor" aria-label="Permalink: Maximum Callouts Exceeded" href="#maximum-callouts-exceeded"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">RTC only allows a maximum of 5 RTC callouts to be sent per ad slot. Whether or not a valid response is received is irrelevant. If a request is dropped prior to actually being sent, it does not count against this limit. For instance, if a publisher specifies 7 URLs to send callouts to, and 2 of them get dropped due to being insecure URLs, then only 5 callouts will actually be sent. In the case that more than 5 callouts are attempted to be sent, only the first 5 will be, and all subsequent callouts will be ignored. An error will be logged to the console for each dropped callout.</p> <p dir="auto">A publisher's custom URLs take precedence over vendor URLs, and are called out in the order in which they were specified. Then, the vendor URLs are called out, also in the order in which they were specified.</p> <div class="markdown-heading" dir="auto"><h5 tabindex="-1" class="heading-element" dir="auto">Network Failure</h5><a id="user-content-network-failure" class="anchor" aria-label="Permalink: Network Failure" href="#network-failure"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">If the XHR GET fails somehow, for example, if network connectivity is lost, the request is lost and an error is logged to the console.</p> <div class="markdown-heading" dir="auto"><h5 tabindex="-1" class="heading-element" dir="auto">Unknown Vendor</h5><a id="user-content-unknown-vendor" class="anchor" aria-label="Permalink: Unknown Vendor" href="#unknown-vendor"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">If a publisher specifies a vendor in their RTC-config that is not actually declared in callout-vendors.js, an error is logged to the console, and no request is sent.</p> <div class="markdown-heading" dir="auto"><h5 tabindex="-1" class="heading-element" dir="auto">Timeout</h5><a id="user-content-timeout" class="anchor" aria-label="Permalink: Timeout" href="#timeout"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">The timeout is either the default timeout of 1000ms, or a shorter timeout specified by the publisher in the RTC-config. If the time for a callout to complete exceeds the timeout, the request is dropped and an error is logged.</p> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Single Request Architecture (SRA) Support</h3><a id="user-content-single-request-architecture-sra-support" class="anchor" aria-label="Permalink: Single Request Architecture (SRA) Support" href="#single-request-architecture-sra-support"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">There is no SRA support at this time. In the event that SRA and RTC are attempted to be used on the same page, RTC will take precedence, and SRA will not be used.</p> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">End-to-End Example</h2><a id="user-content-end-to-end-example" class="anchor" aria-label="Permalink: End-to-End Example" href="#end-to-end-example"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">AmpPublisher.biz uses FadNetwork's Fast Fetch implementation for all of their AMP pages. AmpPublisher.biz wants to start using RTC on their pages to add targeting information to their ad requests. They plan to make callouts to VendorA, VendorB, VendorC, and also to their own custom targeting servers: AmpPublisher.biz/A, and aptgt.biz/B.</p> <p dir="auto">First, AmpPublisher's developer opens up callout-vendors.js to make sure that all of their desired vendors actually support RTC, and find:</p> <div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="/** amp-a4a/0.1/callout-vendors.js */ vendors: { &quot;vendor-a&quot;: { &quot;url&quot;: &quot;https://vendora.com?slot_id=SLOT_ID&amp;start_time=START&quot;, &quot;macros&quot;: [&quot;SLOT_ID&quot;] }, &quot;vendor-b&quot;: { &quot;url&quot;: &quot;https://vendor-b.net/rtc?p_id=PAGE_ID&amp;adw=AD_W&quot;, &quot;macros&quot;: [&quot;PAGE_ID&quot;, &quot;AD_W&quot;] }, &quot;vendorc&quot;: { &quot;url&quot;: &quot;https://www.vendorC.co.uk/ept&quot; } };"><pre><span class="pl-c">/** amp-a4a/0.1/callout-vendors.js */</span> vendors: <span class="pl-kos">{</span> <span class="pl-s">"vendor-a"</span>: <span class="pl-kos">{</span> <span class="pl-s">"url"</span>: <span class="pl-s">"https://vendora.com?slot_id=SLOT_ID&amp;start_time=START"</span><span class="pl-kos">,</span> <span class="pl-s">"macros"</span>: <span class="pl-kos">[</span><span class="pl-s">"SLOT_ID"</span><span class="pl-kos">]</span> <span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-s">"vendor-b"</span>: <span class="pl-kos">{</span> <span class="pl-s">"url"</span>: <span class="pl-s">"https://vendor-b.net/rtc?p_id=PAGE_ID&amp;adw=AD_W"</span><span class="pl-kos">,</span> <span class="pl-s">"macros"</span>: <span class="pl-kos">[</span><span class="pl-s">"PAGE_ID"</span><span class="pl-kos">,</span> <span class="pl-s">"AD_W"</span><span class="pl-kos">]</span> <span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-s">"vendorc"</span>: <span class="pl-kos">{</span> <span class="pl-s">"url"</span>: <span class="pl-s">"https://www.vendorC.co.uk/ept"</span> <span class="pl-kos">}</span> <span class="pl-kos">}</span><span class="pl-kos">;</span></pre></div> <p dir="auto">All of the desired vendors are supported, thus they can use all of them.</p> <p dir="auto">AmpPublisher now wants to check what macros they have available to use from FadNetwork's Fast Implementation, so they open up <strong>amp-ad-network-fadnetwork-impl.js</strong> and check the implementation of <strong>getCustomRealTimeConfigMacros</strong>:</p> <div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="/** amp-ad-network-fadnetwork-impl.js */ export class AmpAdNetworkFadNetworkImpl extends AmpA4A { ... /** @override */ getCustomRealTimeConfigMacros() { return { 'START': Date.now(), 'V_HT': getViewportHeight(), 'V_WT': getViewportWidth() } }"><pre><span class="pl-c">/** amp-ad-network-fadnetwork-impl.js */</span> <span class="pl-k">export</span> <span class="pl-k">class</span> <span class="pl-v">AmpAdNetworkFadNetworkImpl</span> <span class="pl-k">extends</span> <span class="pl-v">AmpA4A</span> <span class="pl-kos">{</span> ... <span class="pl-c">/** <span class="pl-k">@override</span> */</span> <span class="pl-en">getCustomRealTimeConfigMacros</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> <span class="pl-k">return</span> <span class="pl-kos">{</span> <span class="pl-s">'START'</span>: <span class="pl-v">Date</span><span class="pl-kos">.</span><span class="pl-en">now</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">,</span> <span class="pl-s">'V_HT'</span>: <span class="pl-en">getViewportHeight</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">,</span> <span class="pl-s">'V_WT'</span>: <span class="pl-en">getViewportWidth</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">}</span> <span class="pl-kos">}</span><span class="pl-kos"></span></pre></div> <p dir="auto">They see that FadNetwork supports the macros START, V_HT, and V_WT. AmpPublisher then decides that for their two targeting servers they want to call out to, only one of them could actually use these macros.</p> <p dir="auto">AmpPublisher has also decided that the default timeout of 1000ms per callout is too slow for their purposes, and wants to shorten it to 750ms.</p> <p dir="auto">Thus, they define their rtc-config:</p> <div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;amp-ad width=&quot;320&quot; height=&quot;50&quot; type=&quot;fadnetwork&quot; data-slot=&quot;/1234/5678&quot; rtc-config='{ &quot;vendors&quot;: { &quot;vendor-a&quot;: {&quot;SLOT_ID&quot;: &quot;1&quot;}, &quot;vendor-b&quot;: {&quot;PAGE_ID&quot;: &quot;61393&quot;, &quot;AD_W&quot;: &quot;320&quot;}, &quot;vendorc&quot;: {} }, &quot;urls&quot;: [ &quot;https://www.AmpPublisher.biz/A&quot;, &quot;https://www.amptgt.biz/B?d=START&amp;vht=V_HT&amp;vwt=V_WT&quot; ], &quot;timeoutMillis&quot;: 750 }' &gt; &lt;/amp-ad&gt;"><pre><span class="pl-kos">&lt;</span><span class="pl-ent">amp-ad</span> <span class="pl-c1">width</span>="<span class="pl-s">320</span>" <span class="pl-c1">height</span>="<span class="pl-s">50</span>" <span class="pl-c1">type</span>="<span class="pl-s">fadnetwork</span>" <span class="pl-c1">data-slot</span>="<span class="pl-s">/1234/5678</span>" <span class="pl-c1">rtc-config</span>='<span class="pl-s">{</span> <span class="pl-s"> "vendors": {</span> <span class="pl-s"> "vendor-a": {"SLOT_ID": "1"},</span> <span class="pl-s"> "vendor-b": {"PAGE_ID": "61393", "AD_W": "320"},</span> <span class="pl-s"> "vendorc": {}</span> <span class="pl-s"> },</span> <span class="pl-s"> "urls": [</span> <span class="pl-s"> "https://www.AmpPublisher.biz/A",</span> <span class="pl-s"> "https://www.amptgt.biz/B?d=START&amp;vht=V_HT&amp;vwt=V_WT"</span> <span class="pl-s"> ],</span> <span class="pl-s"> "timeoutMillis": 750</span> <span class="pl-s"> }</span>' <span class="pl-kos">&gt;</span> <span class="pl-kos">&lt;/</span><span class="pl-ent">amp-ad</span><span class="pl-kos">&gt;</span></pre></div> <p dir="auto">The setup of the HTML page is now done. At runtime, the next steps happen:</p> <p dir="auto">Real-time-config-manager parses the rtc-config from the ad slot, and uses macro substitution to construct the following 5 URLs:</p> <div class="highlight highlight-source-httpspec notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="https://vendora.com?slot_id=1&amp;start_time=1508779857330 https://vendor-b.net/rtc?p_id=61393&amp;adw=320 https://www.vendorC.co.uk/ept https://www.AmpPublisher.biz/A https://www.amptgt.biz/B?d=1508779857330&amp;vht=1000&amp;vwt=400"><pre><span class="pl-ii">https://vendora.com?slot_id=1&amp;start_time=1508779857330</span> <span class="pl-ii">https://vendor-b.net/rtc?p_id=61393&amp;adw=320</span> <span class="pl-ii">https://www.vendorC.co.uk/ept</span> <span class="pl-ii">https://www.AmpPublisher.biz/A</span> <span class="pl-ii">https://www.amptgt.biz/B?d=1508779857330&amp;vht=1000&amp;vwt=400</span></pre></div> <p dir="auto">These 5 URLs are then called out to as quickly as possible in parallel. A publisher's custom URLs take precedence over vendor URLs, so the actual order in which they send is:</p> <p dir="auto"><a target="_blank" rel="noopener noreferrer" href="/ampproject/amphtml/blob/main/extensions/amp-a4a/RTCDiagram.png"><img src="/ampproject/amphtml/raw/main/extensions/amp-a4a/RTCDiagram.png" alt="Image of RTC Callout Sequence Diagram" style="max-width: 100%;"></a></p> <p dir="auto">The results of the 5 callouts are:</p> <div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="/** Callout 1 response https://www.AmpPublisher.biz/A */ {&quot;targeting&quot;: {&quot;ages&quot;: &quot;18-24&quot;, &quot;g&quot;:[&quot;m&quot;, &quot;f&quot;, &quot;o&quot;]}} /** Callout 2 response https://www.amptgt.biz/B?d=1508779857330&amp;vht=1000&amp;vwt=400 */ No Response, request was timed out due to surpassing 750ms. /** Callout 3 response VendorA */ {&quot;targeting&quot;: {&quot;vacation&quot;: [&quot;beach&quot;, &quot;city&quot;]}} /** Callout 4 response VendorB */ {&quot;targeting&quot;: {&quot;ages&quot;: &quot;35-45&quot;, &quot;i&quot;: {&quot;sport&quot;: &quot;baseball&quot;}}} /** Callout 5 response Vendor C */ {&quot;targeting&quot;: {&quot;i&quot;: {&quot;city&quot;: &quot;NYC&quot;}}}"><pre><span class="pl-c">/** Callout 1 response https://www.AmpPublisher.biz/A */</span> <span class="pl-kos">{</span><span class="pl-s">"targeting"</span>: <span class="pl-kos">{</span><span class="pl-s">"ages"</span>: <span class="pl-s">"18-24"</span><span class="pl-kos">,</span> <span class="pl-s">"g"</span>:<span class="pl-kos">[</span><span class="pl-s">"m"</span><span class="pl-kos">,</span> <span class="pl-s">"f"</span><span class="pl-kos">,</span> <span class="pl-s">"o"</span><span class="pl-kos">]</span><span class="pl-kos">}</span><span class="pl-kos">}</span> <span class="pl-c">/** Callout 2 response https://www.amptgt.biz/B?d=1508779857330&amp;vht=1000&amp;vwt=400 */</span> <span class="pl-v">No</span> <span class="pl-v">Response</span><span class="pl-kos">,</span> <span class="pl-s1">request</span> <span class="pl-s1">was</span> <span class="pl-s1">timed</span> <span class="pl-s1">out</span> <span class="pl-s1">due</span> <span class="pl-s1">to</span> <span class="pl-s1">surpassing</span> <span class="pl-c1">750</span><span class="pl-s1">ms</span><span class="pl-kos">.</span> <span class="pl-c">/** Callout 3 response VendorA */</span> <span class="pl-kos">{</span><span class="pl-s">"targeting"</span>: <span class="pl-kos">{</span><span class="pl-s">"vacation"</span>: <span class="pl-kos">[</span><span class="pl-s">"beach"</span><span class="pl-kos">,</span> <span class="pl-s">"city"</span><span class="pl-kos">]</span><span class="pl-kos">}</span><span class="pl-kos">}</span> <span class="pl-c">/** Callout 4 response VendorB */</span> <span class="pl-kos">{</span><span class="pl-s">"targeting"</span>: <span class="pl-kos">{</span><span class="pl-s">"ages"</span>: <span class="pl-s">"35-45"</span><span class="pl-kos">,</span> <span class="pl-s">"i"</span>: <span class="pl-kos">{</span><span class="pl-s">"sport"</span>: <span class="pl-s">"baseball"</span><span class="pl-kos">}</span><span class="pl-kos">}</span><span class="pl-kos">}</span> <span class="pl-c">/** Callout 5 response Vendor C */</span> <span class="pl-kos">{</span><span class="pl-s">"targeting"</span>: <span class="pl-kos">{</span><span class="pl-s">"i"</span>: <span class="pl-kos">{</span><span class="pl-s">"city"</span>: <span class="pl-s">"NYC"</span><span class="pl-kos">}</span><span class="pl-kos">}</span><span class="pl-kos">}</span></pre></div> <p dir="auto">AmpA4a builds a promise to an array of RTC Response Objects, and passes that Promise to <strong>getAdUrl</strong> in FadNetwork's Fast Fetch Implementation, which then resolves this promise.</p> <div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="/** amp-ad-network-fadnetwork-impl.js */ export class AmpAdNetworkFadNetworkImpl extends AmpA4A { ... /** @override */ getAdUrl(opt_rtcResponsesPromise) { return opt_rtcResponsesPromise.then(rtcResponseArray =&gt; { buildAndSendAdUrl(rtcResponseArray); }); } }"><pre><span class="pl-c">/** amp-ad-network-fadnetwork-impl.js */</span> <span class="pl-k">export</span> <span class="pl-k">class</span> <span class="pl-v">AmpAdNetworkFadNetworkImpl</span> <span class="pl-k">extends</span> <span class="pl-v">AmpA4A</span> <span class="pl-kos">{</span> ... <span class="pl-c">/** <span class="pl-k">@override</span> */</span> <span class="pl-en">getAdUrl</span><span class="pl-kos">(</span><span class="pl-s1">opt_rtcResponsesPromise</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> <span class="pl-k">return</span> <span class="pl-s1">opt_rtcResponsesPromise</span><span class="pl-kos">.</span><span class="pl-en">then</span><span class="pl-kos">(</span><span class="pl-s1">rtcResponseArray</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span> <span class="pl-en">buildAndSendAdUrl</span><span class="pl-kos">(</span><span class="pl-s1">rtcResponseArray</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span> <span class="pl-kos">}</span> <span class="pl-kos">}</span></pre></div> <p dir="auto">In this specific case, the Promise resolves to the following array:</p> <div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="[ /** Callout 1 RTC Response Object */ { response: '{&quot;targeting&quot;: {&quot;ages&quot;: &quot;18-24&quot;, &quot;g&quot;:[&quot;m&quot;, &quot;f&quot;, &quot;o&quot;]}}', rtcTime: 685, callout: 'www.AmpPublisher.biz', }, /** Callout 2 RTC Response Object */ {error: 'timeout', rtcTime: 750, callout: 'www.amptgt.biz'}, /** Callout 3 RTC Response Object */ {error: 'malformed_json_response', rtcTime: 580, callout: 'vendora'}, /** Callout 4 RTC Response Object */ { response: '{&quot;targeting&quot;: {&quot;ages&quot;: &quot;35-45&quot;, &quot;i&quot;: {&quot;sport&quot;: &quot;baseball&quot;}}}', rtcTime: 700, callout: 'vendor-b', }, /** Callout 5 RTC Response Object */ { response: '{&quot;targeting&quot;: {&quot;i&quot;: {&quot;city&quot;: &quot;NYC&quot;}}}', rtcTime: 730, callout: 'vendorc', }, ];"><pre><span class="pl-kos">[</span> <span class="pl-c">/** Callout 1 RTC Response Object */</span> <span class="pl-kos">{</span> <span class="pl-c1">response</span>: <span class="pl-s">'{"targeting": {"ages": "18-24", "g":["m", "f", "o"]}}'</span><span class="pl-kos">,</span> <span class="pl-c1">rtcTime</span>: <span class="pl-c1">685</span><span class="pl-kos">,</span> <span class="pl-c1">callout</span>: <span class="pl-s">'www.AmpPublisher.biz'</span><span class="pl-kos">,</span> <span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-c">/** Callout 2 RTC Response Object */</span> <span class="pl-kos">{</span><span class="pl-c1">error</span>: <span class="pl-s">'timeout'</span><span class="pl-kos">,</span> <span class="pl-c1">rtcTime</span>: <span class="pl-c1">750</span><span class="pl-kos">,</span> <span class="pl-c1">callout</span>: <span class="pl-s">'www.amptgt.biz'</span><span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-c">/** Callout 3 RTC Response Object */</span> <span class="pl-kos">{</span><span class="pl-c1">error</span>: <span class="pl-s">'malformed_json_response'</span><span class="pl-kos">,</span> <span class="pl-c1">rtcTime</span>: <span class="pl-c1">580</span><span class="pl-kos">,</span> <span class="pl-c1">callout</span>: <span class="pl-s">'vendora'</span><span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-c">/** Callout 4 RTC Response Object */</span> <span class="pl-kos">{</span> <span class="pl-c1">response</span>: <span class="pl-s">'{"targeting": {"ages": "35-45", "i": {"sport": "baseball"}}}'</span><span class="pl-kos">,</span> <span class="pl-c1">rtcTime</span>: <span class="pl-c1">700</span><span class="pl-kos">,</span> <span class="pl-c1">callout</span>: <span class="pl-s">'vendor-b'</span><span class="pl-kos">,</span> <span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-c">/** Callout 5 RTC Response Object */</span> <span class="pl-kos">{</span> <span class="pl-c1">response</span>: <span class="pl-s">'{"targeting": {"i": {"city": "NYC"}}}'</span><span class="pl-kos">,</span> <span class="pl-c1">rtcTime</span>: <span class="pl-c1">730</span><span class="pl-kos">,</span> <span class="pl-c1">callout</span>: <span class="pl-s">'vendorc'</span><span class="pl-kos">,</span> <span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-kos">]</span><span class="pl-kos">;</span></pre></div> <p dir="auto"><strong>Example of Resolved Value of opt_rtcResponsesPromise passed to getAdUrl</strong></p> <p dir="auto"><strong>_Explanation of Errors in RTC Responses _</strong></p> <p dir="auto"><em>Callout 2 surpassed the timeout of 750ms, so it gets dropped and an error is logged to the console.</em></p> <p dir="auto"><em>Callout 3 returns unparseable JSON, so it gets dropped and an error is logged.</em></p> <p dir="auto"><em>Callout 1, 4, and 5 all return valid JSON and cause no errors</em></p> <p dir="auto">The Fast Fetch Implementation for FadNetwork then uses this array of RTC response objects to build and send the ad request URL. It is at the discretion of FadNetwork to merge these parameters however they see fit. In this example, FadNetwork simply does a deep merge of all the successful RTC callout responses, with the last response given precedence in case of collision, and gets the resulting JSON:</p> <div class="highlight highlight-source-json notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="{ &quot;targeting&quot;: { &quot;ages&quot;: &quot;35-45&quot;, &quot;g&quot;: [&quot;m&quot;, &quot;f&quot;, &quot;o&quot;], &quot;i&quot;: {&quot;sport&quot;: &quot;baseball&quot;, &quot;city&quot;: &quot;NYC&quot;} } }"><pre>{ <span class="pl-ent">"targeting"</span>: { <span class="pl-ent">"ages"</span>: <span class="pl-s"><span class="pl-pds">"</span>35-45<span class="pl-pds">"</span></span>, <span class="pl-ent">"g"</span>: [<span class="pl-s"><span class="pl-pds">"</span>m<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>f<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>o<span class="pl-pds">"</span></span>], <span class="pl-ent">"i"</span>: {<span class="pl-ent">"sport"</span>: <span class="pl-s"><span class="pl-pds">"</span>baseball<span class="pl-pds">"</span></span>, <span class="pl-ent">"city"</span>: <span class="pl-s"><span class="pl-pds">"</span>NYC<span class="pl-pds">"</span></span>} } }</pre></div> <p dir="auto"><strong>Result of merging successful RTC Callouts 1, 4, and 5</strong></p> <p dir="auto">FadNetwork then constructs and encodes their Ad URL as:</p> <div class="highlight highlight-source-httpspec notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="https://www.fadnetwork.biz/adServer?%7B%E2%80%9Ctargeting%E2%80%9D:%20%7B%E2%80%9Cages%E2%80%9D:%20%E2%80%9C35-45%E2%80%9D,%20%E2%80%9Cg%E2%80%9D:%5B%E2%80%9Cm%E2%80%9D,%20%E2%80%9Cf%E2%80%9D,%20%E2%80%9Co%E2%80%9D%5D,%20%E2%80%9Ci%E2%80%9D:%20%7B%E2%80%9Csport%E2%80%9D:%20%E2%80%9Cbaseball%E2%80%9D,%20%E2%80%9Ccity%E2%80%9D:%20%E2%80%9CNYC%E2%80%9D%7D%7D"><pre><span class="pl-ii">https://www.fadnetwork.biz/adServer?%7B%E2%80%9Ctargeting%E2%80%9D:%20%7B%E2%80%9Cages%E2%80%9D:%20%E2%80%9C35-45%E2%80%9D,%20%E2%80%9Cg%E2%80%9D:%5B%E2%80%9Cm%E2%80%9D,%20%E2%80%9Cf%E2%80%9D,%20%E2%80%9Co%E2%80%9D%5D,%20%E2%80%9Ci%E2%80%9D:%20%7B%E2%80%9Csport%E2%80%9D:%20%E2%80%9Cbaseball%E2%80%9D,%20%E2%80%9Ccity%E2%80%9D:%20%E2%80%9CNYC%E2%80%9D%7D%7D</span></pre></div> <p dir="auto"><strong>FadNetwork's resulting Ad Request URL (use decodeURI to see original json)</strong></p> <p dir="auto">From this point forward, all Fast Fetch behavior is exactly the same as non-RTC use cases, and regular Fast Fetch documentation may be consulted for additional questions.</p> </article></div><button hidden=""></button></section></div></div></div> <!-- --> <!-- --> </div></div></div><div class="Box-sc-g0xbh4-0"></div></div></div></div></div><div id="find-result-marks-container" class="Box-sc-g0xbh4-0 cCoXib"></div><button hidden="" data-testid="" data-hotkey-scope="read-only-cursor-text-area"></button><button hidden=""></button></div> <!-- --> <!-- --> <script type="application/json" id="__PRIMER_DATA_:R0:__">{"resolvedServerColorMode":"day"}</script></div> </react-app> </turbo-frame> </div> </turbo-frame> </main> </div> </div> <footer class="footer pt-8 pb-6 f6 color-fg-muted p-responsive" role="contentinfo" > <h2 class='sr-only'>Footer</h2> <div class="d-flex flex-justify-center flex-items-center flex-column-reverse flex-lg-row flex-wrap flex-lg-nowrap"> <div class="d-flex flex-items-center flex-shrink-0 mx-2"> <a aria-label="Homepage" title="GitHub" class="footer-octicon mr-2" href="https://github.com"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-mark-github"> <path d="M12.5.75C6.146.75 1 5.896 1 12.25c0 5.089 3.292 9.387 7.863 10.91.575.101.79-.244.79-.546 0-.273-.014-1.178-.014-2.142-2.889.532-3.636-.704-3.866-1.35-.13-.331-.69-1.352-1.18-1.625-.402-.216-.977-.748-.014-.762.906-.014 1.553.834 1.769 1.179 1.035 1.74 2.688 1.25 3.349.948.1-.747.402-1.25.733-1.538-2.559-.287-5.232-1.279-5.232-5.678 0-1.25.445-2.285 1.178-3.09-.115-.288-.517-1.467.115-3.048 0 0 .963-.302 3.163 1.179.92-.259 1.897-.388 2.875-.388.977 0 1.955.13 2.875.388 2.2-1.495 3.162-1.179 3.162-1.179.633 1.581.23 2.76.115 3.048.733.805 1.179 1.825 1.179 3.09 0 4.413-2.688 5.39-5.247 5.678.417.36.776 1.05.776 2.128 0 1.538-.014 2.774-.014 3.162 0 .302.216.662.79.547C20.709 21.637 24 17.324 24 12.25 24 5.896 18.854.75 12.5.75Z"></path> </svg> </a> <span> &copy; 2025 GitHub,&nbsp;Inc. </span> </div> <nav aria-label="Footer"> <h3 class="sr-only" id="sr-footer-heading">Footer navigation</h3> <ul class="list-style-none d-flex flex-justify-center flex-wrap mb-2 mb-lg-0" aria-labelledby="sr-footer-heading"> <li class="mx-2"> <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to Terms&quot;,&quot;label&quot;:&quot;text:terms&quot;}" href="https://docs.github.com/site-policy/github-terms/github-terms-of-service" data-view-component="true" class="Link--secondary Link">Terms</a> </li> <li class="mx-2"> <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to privacy&quot;,&quot;label&quot;:&quot;text:privacy&quot;}" href="https://docs.github.com/site-policy/privacy-policies/github-privacy-statement" data-view-component="true" class="Link--secondary Link">Privacy</a> </li> <li class="mx-2"> <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to security&quot;,&quot;label&quot;:&quot;text:security&quot;}" href="https://github.com/security" data-view-component="true" class="Link--secondary Link">Security</a> </li> <li class="mx-2"> <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to status&quot;,&quot;label&quot;:&quot;text:status&quot;}" href="https://www.githubstatus.com/" data-view-component="true" class="Link--secondary Link">Status</a> </li> <li class="mx-2"> <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to docs&quot;,&quot;label&quot;:&quot;text:docs&quot;}" href="https://docs.github.com/" data-view-component="true" class="Link--secondary Link">Docs</a> </li> <li class="mx-2"> <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to contact&quot;,&quot;label&quot;:&quot;text:contact&quot;}" href="https://support.github.com?tags=dotcom-footer" data-view-component="true" class="Link--secondary Link">Contact</a> </li> <li class="mx-2" > <cookie-consent-link> <button type="button" class="Link--secondary underline-on-hover border-0 p-0 color-bg-transparent" data-action="click:cookie-consent-link#showConsentManagement" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;cookies&quot;,&quot;context&quot;:&quot;subfooter&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;cookies_link_subfooter_footer&quot;}" > Manage cookies </button> </cookie-consent-link> </li> <li class="mx-2"> <cookie-consent-link> <button type="button" class="Link--secondary underline-on-hover border-0 p-0 color-bg-transparent" data-action="click:cookie-consent-link#showConsentManagement" data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;dont_share_info&quot;,&quot;context&quot;:&quot;subfooter&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;dont_share_info_link_subfooter_footer&quot;}" > Do not share my personal information </button> </cookie-consent-link> </li> </ul> </nav> </div> </footer> <ghcc-consent id="ghcc" class="position-fixed bottom-0 left-0" style="z-index: 999999" data-initial-cookie-consent-allowed="" data-cookie-consent-required="false"></ghcc-consent> <div id="ajax-error-message" class="ajax-error-message flash flash-error" hidden> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert"> <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path> </svg> <button type="button" class="flash-close js-ajax-error-dismiss" aria-label="Dismiss error"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x"> <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path> </svg> </button> You can’t perform that action at this time. </div> <template id="site-details-dialog"> <details class="details-reset details-overlay details-overlay-dark lh-default color-fg-default hx_rsm" open> <summary role="button" aria-label="Close dialog"></summary> <details-dialog class="Box Box--overlay d-flex flex-column anim-fade-in fast hx_rsm-dialog hx_rsm-modal"> <button class="Box-btn-octicon m-0 btn-octicon position-absolute right-0 top-0" type="button" aria-label="Close dialog" data-close-dialog> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x"> <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path> </svg> </button> <div class="octocat-spinner my-6 js-details-dialog-spinner"></div> </details-dialog> </details> </template> <div class="Popover js-hovercard-content position-absolute" style="display: none; outline: none;"> <div class="Popover-message Popover-message--bottom-left Popover-message--large Box color-shadow-large" style="width:360px;"> </div> </div> <template id="snippet-clipboard-copy-button"> <div class="zeroclipboard-container position-absolute right-0 top-0"> <clipboard-copy aria-label="Copy" class="ClipboardButton btn js-clipboard-copy m-2 p-0" data-copy-feedback="Copied!" data-tooltip-direction="w"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon m-2"> <path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path> </svg> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check js-clipboard-check-icon color-fg-success d-none m-2"> <path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path> </svg> </clipboard-copy> </div> </template> <template id="snippet-clipboard-copy-button-unpositioned"> <div class="zeroclipboard-container"> <clipboard-copy aria-label="Copy" class="ClipboardButton btn btn-invisible js-clipboard-copy m-2 p-0 d-flex flex-justify-center flex-items-center" data-copy-feedback="Copied!" data-tooltip-direction="w"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon"> <path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path> </svg> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check js-clipboard-check-icon color-fg-success d-none"> <path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path> </svg> </clipboard-copy> </div> </template> </div> <div id="js-global-screen-reader-notice" class="sr-only mt-n1" aria-live="polite" aria-atomic="true" ></div> <div id="js-global-screen-reader-notice-assertive" class="sr-only mt-n1" aria-live="assertive" aria-atomic="true"></div> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10