Getting started with congress

Introduction

The congress package provides access to the Congress.gov API. It allows political scientists, journalists, and policy analysts to gather legislative data programmatically. This includes bills, amendments, member activity, nominations, committee outputs, reports, and more. All requests can optionally be returned in tidy format.

This vignette introduces core workflows using congress: how to authenticate, handle pagination, and query the API.

library(congress)

Authentication

The Congress.gov API requires an access key. After requesting a key from api.congress.gov, use the set_congress_key() helper to authenticate:

set_congress_key('YOUR-API-KEY', install = TRUE)

This saves the key to your .Renviron, making it available in future sessions.

If you prefer to keep the key temporary, use:

Sys.setenv(CONGRESS_KEY = 'YOUR-API-KEY')

Once set, congress handles key usage internally. No manual headers or tokens are needed.

It is recommended that you authenticate by placing your key in your .Renviron file to avoid accidentally sharing your person, private key.

Filtering by Date

All endpoints accept from_date and to_date. This is often misleading, so beware. It does not filter by the date of the action, but rather the date of the last update. As such, this is most useful if you are scraping over time. For example, if you run an analysis monthly, then you can use the from_date and to_date arguments to limit the results to the time since your last scrape.

cong_bill(congress = 118, from_date = '2025-04-01', to_date = '2025-05-23')
#> # A tibble: 20 × 12
#>    congress latest_action_action_date latest_action_action_…¹ latest_action_text
#>    <chr>    <date>                    <chr>                   <chr>             
#>  1 118      2024-12-24                10:13:00                Held at the desk. 
#>  2 118      2024-12-20                <NA>                    Referred to the C…
#>  3 118      2024-12-19                18:06:21                Held at the desk. 
#>  4 118      2024-12-19                <NA>                    Read twice and re…
#>  5 118      2024-12-19                <NA>                    Read twice and re…
#>  6 118      2024-12-18                18:26:07                Held at the desk. 
#>  7 118      2024-12-18                <NA>                    Read twice and re…
#>  8 118      2024-12-17                <NA>                    Referred to the C…
#>  9 118      2024-12-16                <NA>                    Read twice and re…
#> 10 118      2024-12-12                <NA>                    Read twice and re…
#> 11 118      2024-12-12                <NA>                    Read twice and re…
#> 12 118      2024-12-11                16:55:14                Held at the desk. 
#> 13 118      2024-12-05                <NA>                    Resolution agreed…
#> 14 118      2024-11-21                <NA>                    Placed on Senate …
#> 15 118      2024-11-21                <NA>                    Referred to the C…
#> 16 118      2024-11-21                <NA>                    Placed on Senate …
#> 17 118      2024-11-21                <NA>                    Placed on Senate …
#> 18 118      2024-11-21                <NA>                    Placed on Senate …
#> 19 118      2024-11-21                <NA>                    Placed on Senate …
#> 20 118      2024-11-21                <NA>                    Placed on Senate …
#> # ℹ abbreviated name: ¹​latest_action_action_time
#> # ℹ 8 more variables: number <chr>, origin_chamber <chr>,
#> #   origin_chamber_code <chr>, title <chr>, type <chr>, update_date <date>,
#> #   update_date_including_text <date>, url <chr>

Retrieving Legislation

cong_bill() retrieves bills, sorted by their most recent action date.

bills <- cong_bill()
bills
#> # A tibble: 20 × 11
#>    congress latest_action_action_date latest_action_text   number origin_chamber
#>    <chr>    <date>                    <chr>                <chr>  <chr>         
#>  1 119      2025-08-29                Referred to the Hou… 665    House         
#>  2 119      2025-08-29                Referred to the Hou… 5064   House         
#>  3 119      2025-08-29                Referred to the Com… 5061   House         
#>  4 119      2025-08-29                Referred to the Hou… 5067   House         
#>  5 119      2025-08-29                Referred to the Com… 667    House         
#>  6 119      2025-08-29                Referred to the Hou… 666    House         
#>  7 119      2025-08-29                Referred to the Hou… 5071   House         
#>  8 119      2025-08-29                Referred to the Hou… 117    House         
#>  9 119      2025-08-29                Referred to the Hou… 5072   House         
#> 10 119      2025-08-29                Referred to the Hou… 5077   House         
#> 11 119      2025-08-29                Referred to the Hou… 5070   House         
#> 12 119      2025-08-29                Referred to the Com… 5076   House         
#> 13 119      2025-08-29                Referred to the Hou… 5065   House         
#> 14 119      2025-08-29                Referred to the Hou… 5074   House         
#> 15 119      2025-08-29                Referred to the Hou… 5075   House         
#> 16 119      2025-08-29                Referred to the Hou… 5062   House         
#> 17 119      2025-08-29                Referred to the Com… 5060   House         
#> 18 119      2025-08-29                Referred to the Hou… 5073   House         
#> 19 119      2025-08-29                Referred to the Hou… 5063   House         
#> 20 119      2025-08-29                Referred to the Hou… 5069   House         
#> # ℹ 6 more variables: origin_chamber_code <chr>, title <chr>, type <chr>,
#> #   update_date <date>, update_date_including_text <date>, url <chr>

By default, this returns the 20 most recently updated bills across all chambers and types. Narrow the scope with the congress and type arguments:

bills_118 <- cong_bill(congress = 118, type = 'hr', limit = 5)
bills_118
#> # A tibble: 5 × 11
#>   congress latest_action_action_date latest_action_text    number origin_chamber
#>   <chr>    <date>                    <chr>                 <chr>  <chr>         
#> 1 118      2025-01-06                Became Public Law No… 4984   House         
#> 2 118      2025-01-05                Became Public Law No… 82     House         
#> 3 118      2025-01-04                Became Public Law No… 9775   House         
#> 4 118      2025-01-04                Became Public Law No… 9600   House         
#> 5 118      2025-01-04                Became Public Law No… 9592   House         
#> # ℹ 6 more variables: origin_chamber_code <chr>, title <chr>, type <chr>,
#> #   update_date <date>, update_date_including_text <date>, url <chr>

The result is a tibble with sponsor, title, dates, latest action, and other details. Each row represents a single bill, with a summary of its most recent action.

To inspect a specific bill by number:

hr1 <- cong_bill(congress = 118, type = 'hr', number = 1)
hr1
#> # A tibble: 1 × 36
#>   actions_count actions_url   amendments_count amendments_url cbo_cost_estimates
#>           <int> <chr>                    <int> <chr>          <list>            
#> 1            93 https://api.…               37 https://api.c… <list [2]>        
#> # ℹ 31 more variables: committees_count <int>, committees_url <chr>,
#> #   congress <int>, constitutional_authority_statement_text <chr>,
#> #   cosponsors_count <int>,
#> #   cosponsors_count_including_withdrawn_cosponsors <int>,
#> #   cosponsors_url <chr>, introduced_date <date>,
#> #   latest_action_action_date <date>, latest_action_action_time <chr>,
#> #   latest_action_text <chr>, legislation_url <chr>, number <chr>, …

Legislative Details

Each bill can have multiple related pieces of information, including actions, amendments, committees, cosponsors, related bills, subjects, summaries, text (for the full text), and titles. Access each of these with the item argument:

actions <- cong_bill(congress = 118, type = 'hr', number = 1, item = 'actions')
actions
#> # A tibble: 20 × 16
#>    action_code action_date action_time source_system_code source_system_name 
#>    <chr>       <date>      <chr>       <chr>              <chr>              
#>  1 H38900      2023-03-30  11:47:06    2                  House floor actions
#>  2 H38310      2023-03-30  11:47:05    2                  House floor actions
#>  3 H37100      2023-03-30  11:47:03    2                  House floor actions
#>  4 8000        2023-03-30  11:47:03    9                  Library of Congress
#>  5 H36210      2023-03-30  11:40:22    2                  House floor actions
#>  6 H8A000      2023-03-30  11:34:01    2                  House floor actions
#>  7 H36200      2023-03-30  11:33:36    2                  House floor actions
#>  8 H34400      2023-03-30  11:32:43    2                  House floor actions
#>  9 H35000      2023-03-30  11:32:27    2                  House floor actions
#> 10 H32600      2023-03-30  11:32:12    2                  House floor actions
#> 11 H8D000      2023-03-30  10:18:08    2                  House floor actions
#> 12 H8D000      2023-03-30  10:15:32    2                  House floor actions
#> 13 H8D000      2023-03-30  10:07:33    2                  House floor actions
#> 14 H8D000      2023-03-30  10:05:22    2                  House floor actions
#> 15 H8D000      2023-03-30  09:58:46    2                  House floor actions
#> 16 H8D000      2023-03-30  09:57:25    2                  House floor actions
#> 17 H8D000      2023-03-30  09:49:16    2                  House floor actions
#> 18 H8D000      2023-03-30  09:40:31    2                  House floor actions
#> 19 H8D000      2023-03-30  09:34:18    2                  House floor actions
#> 20 H8D000      2023-03-30  09:31:51    2                  House floor actions
#> # ℹ 11 more variables: text <chr>, type <chr>, recorded_votes_chamber <chr>,
#> #   recorded_votes_congress <chr>, recorded_votes_date <dttm>,
#> #   recorded_votes_roll_number <chr>, recorded_votes_session_number <chr>,
#> #   recorded_votes_url <chr>, committees_name <chr>,
#> #   committees_system_code <chr>, committees_url <chr>

This returns a tibble of all actions taken on the bill, including dates and descriptions.

cosponsors <- cong_bill(congress = 118, type = 'hr', number = 1, item = 'cosponsors')
cosponsors
#> # A tibble: 20 × 11
#>    bioguide_id district first_name full_name     is_original_cosponsor last_name
#>    <chr>       <chr>    <chr>      <chr>         <chr>                 <chr>    
#>  1 M001159     5        Cathy      "Rep. McMorr… TRUE                  Rodgers  
#>  2 W000821     4        Bruce      "Rep. Wester… TRUE                  Westerman
#>  3 G000546     6        SAM        "Rep. Graves… TRUE                  GRAVES   
#>  4 S001196     21       Elise      "Rep. Stefan… FALSE                 Stefanik 
#>  5 G000577     6        Garret     "Rep. Graves… FALSE                 Graves   
#>  6 M001204     9        Daniel     "Rep. Meuser… FALSE                 Meuser   
#>  7 M001177     5        Tom        "Rep. McClin… FALSE                 McClinto…
#>  8 F000465     3        A.         "Rep. Fergus… FALSE                 Ferguson 
#>  9 B000825     3        Lauren     "Rep. Boeber… FALSE                 Boebert  
#> 10 J000302     13       John       "Rep. Joyce,… FALSE                 Joyce    
#> 11 C001114     3        John       "Rep. Curtis… FALSE                 Curtis   
#> 12 A000377     0        Kelly      "Rep. Armstr… FALSE                 Armstrong
#> 13 L000566     5        Robert     "Rep. Latta,… FALSE                 Latta    
#> 14 A000372     12       Rick       "Rep. Allen,… FALSE                 Allen    
#> 15 P000048     11       August     "Rep. Pfluge… FALSE                 Pfluger  
#> 16 D000628     2        Neal       "Rep. Dunn, … FALSE                 Dunn     
#> 17 C001103     1        Earl       "Rep. Carter… FALSE                 Carter   
#> 18 C001120     2        Dan        "Rep. Crensh… FALSE                 Crenshaw 
#> 19 B001306     12       Troy       "Rep. Balder… FALSE                 Balderson
#> 20 B001248     26       Michael    "Rep. Burges… FALSE                 Burgess  
#> # ℹ 5 more variables: middle_name <chr>, party <chr>, sponsorship_date <date>,
#> #   state <chr>, url <chr>

Other types of actions taken by Congress can be accessed through other endpoints. For example, to focus on amendments, use cong_amendment().

amendments <- cong_amendment(congress = 118, limit = 50)
amendments
#> # A tibble: 50 × 10
#>    congress description            latest_action_action…¹ latest_action_action…²
#>    <chr>    <chr>                  <date>                 <chr>                 
#>  1 118      "An amendment numbere… 2023-01-26             14:00:19              
#>  2 118      "An amendment numbere… 2023-01-26             17:39:08              
#>  3 118      "An amendment numbere… 2023-01-26             17:42:24              
#>  4 118      "An amendment numbere… 2023-01-26             17:35:50              
#>  5 118      "An amendment numbere… 2023-01-26             17:46:05              
#>  6 118      "An amendment numbere… 2023-01-26             17:31:18              
#>  7 118      "An amendment numbere… 2023-01-26             14:37:00              
#>  8 118      "An amendment numbere… 2023-01-26             14:40:15              
#>  9 118      "An amendment numbere… 2023-01-26             14:42:47              
#> 10 118      "An amendment numbere… 2023-01-26             14:46:58              
#> # ℹ 40 more rows
#> # ℹ abbreviated names: ¹​latest_action_action_date, ²​latest_action_action_time
#> # ℹ 6 more variables: latest_action_text <chr>, number <chr>, type <chr>,
#> #   update_date <dttm>, url <chr>, purpose <chr>

Or target a specific one. We do this by specifying that we want the Senate Amendment 2137 from the 117th Congress:

amend_detail <- cong_amendment(congress = 117, type = 'samdt', number = 2137)
amend_detail
#> # A tibble: 1 × 27
#>   actions_count actions_url            amended_bill_congress amended_bill_number
#>           <int> <chr>                                  <int> <chr>              
#> 1            18 https://api.congress.…                   117 3684               
#> # ℹ 23 more variables: amended_bill_origin_chamber <chr>,
#> #   amended_bill_origin_chamber_code <chr>, amended_bill_title <chr>,
#> #   amended_bill_type <chr>, amended_bill_update_date_including_text <date>,
#> #   amended_bill_url <chr>, amendments_to_amendment_count <int>,
#> #   amendments_to_amendment_url <chr>, chamber <chr>, congress <int>,
#> #   cosponsors_count <int>,
#> #   cosponsors_count_including_withdrawn_cosponsors <int>, …

Member Activity

cong_member() helps link individual lawmakers to legislative behavior. Use the bioguide argument to target a specific member.

sponsored <- cong_member(bioguide = 'W000817', item = 'sponsored-legislation')
sponsored
#> # A tibble: 20 × 10
#>    amendment_number congress introduced_date url          latest_action_action…¹
#>    <chr>            <chr>    <date>          <chr>        <date>                
#>  1 3544             119      2025-08-01      https://api… NA                    
#>  2 3526             119      2025-08-01      https://api… NA                    
#>  3 3527             119      2025-08-01      https://api… NA                    
#>  4 3524             119      2025-08-01      https://api… NA                    
#>  5 3525             119      2025-08-01      https://api… NA                    
#>  6 <NA>             119      2025-07-28      https://api… 2025-07-28            
#>  7 <NA>             119      2025-07-17      https://api… 2025-07-17            
#>  8 2895             119      2025-07-16      https://api… NA                    
#>  9 <NA>             119      2025-07-16      https://api… 2025-07-16            
#> 10 <NA>             119      2025-07-08      https://api… 2025-07-08            
#> 11 2414             119      2025-06-29      https://api… 2025-06-30            
#> 12 <NA>             119      2025-06-26      https://api… 2025-06-26            
#> 13 2396             119      2025-06-29      https://api… NA                    
#> 14 2400             119      2025-06-29      https://api… NA                    
#> 15 2399             119      2025-06-29      https://api… NA                    
#> 16 2398             119      2025-06-29      https://api… NA                    
#> 17 2395             119      2025-06-29      https://api… NA                    
#> 18 2397             119      2025-06-29      https://api… NA                    
#> 19 2392             119      2025-06-29      https://api… NA                    
#> 20 2393             119      2025-06-29      https://api… NA                    
#> # ℹ abbreviated name: ¹​latest_action_action_date
#> # ℹ 5 more variables: latest_action_text <chr>, number <chr>, title <chr>,
#> #   type <chr>, policy_area_name <chr>

This returns all legislation introduced by Senator Elizabeth Warren in the 118th Congress. The endpoint tracks various components of a member of Congress’s work, such as cosponsored-legislation.

To look up bioguide information, there is an official site: https://bioguide.congress.gov/. Responses from cong_member() also include bioguide IDs, so you can use them to cross-reference with other datasets.

Committee Work

A significant portion of work in Congress is conducted by committee. We can use cong_committee() to access committee information:

committees <- cong_committee(congress = 118)
committees
#> # A tibble: 20 × 10
#>    chamber committee_type_code  name       system_code update_date         url  
#>    <chr>   <chr>                <chr>      <chr>       <dttm>              <chr>
#>  1 Joint   Joint                Joint Eco… jhje00      2025-05-16 20:39:59 http…
#>  2 Joint   Commission or Caucus Congressi… jcpk00      2025-02-24 16:33:20 http…
#>  3 House   Select               Select Su… hlfd00      2025-01-04 11:54:09 http…
#>  4 House   Subcommittee         Select Su… hlvc00      2025-01-04 11:53:18 http…
#>  5 House   Task Force           Task Forc… htzt00      2025-01-04 11:38:24 http…
#>  6 Senate  Standing             Veterans'… ssva00      2025-01-03 20:48:25 http…
#>  7 Senate  Standing             Rules and… ssra00      2025-01-03 20:48:25 http…
#>  8 Senate  Standing             Small Bus… sssb00      2025-01-03 20:48:25 http…
#>  9 Senate  Subcommittee         Governmen… ssga22      2025-01-03 20:48:24 http…
#> 10 Senate  Subcommittee         Criminal … ssju22      2025-01-03 20:48:24 http…
#> 11 Senate  Subcommittee         Privacy, … ssju28      2025-01-03 20:48:24 http…
#> 12 Senate  Subcommittee         Competiti… ssju01      2025-01-03 20:48:24 http…
#> 13 Senate  Subcommittee         Primary H… sshr12      2025-01-03 20:48:24 http…
#> 14 Senate  Subcommittee         Immigrati… ssju04      2025-01-03 20:48:24 http…
#> 15 Senate  Subcommittee         Intellect… ssju26      2025-01-03 20:48:24 http…
#> 16 Senate  Standing             Health, E… sshr00      2025-01-03 20:48:24 http…
#> 17 Senate  Subcommittee         Constitut… ssju21      2025-01-03 20:48:24 http…
#> 18 Senate  Subcommittee         Human Rig… ssju27      2025-01-03 20:48:24 http…
#> 19 Senate  Subcommittee         Employmen… sshr11      2025-01-03 20:48:24 http…
#> 20 Senate  Subcommittee         Children … sshr09      2025-01-03 20:48:24 http…
#> # ℹ 4 more variables: parent_name <chr>, parent_system_code <chr>,
#> #   parent_url <chr>, subcommittees <list>

To get reports or prints from a committee, use the corresponding functions:

reports <- cong_committee_report(congress = 118, limit = 5)
reports
#> # A tibble: 5 × 8
#>   chamber citation         congress number part  type  update_date         url  
#>   <chr>   <chr>            <chr>    <chr>  <chr> <chr> <dttm>              <chr>
#> 1 House   H. Rept. 118-578 118      578    1     HRPT  2025-07-31 16:27:30 http…
#> 2 House   H. Rept. 118-555 118      555    1     HRPT  2025-07-31 16:27:30 http…
#> 3 House   H. Rept. 118-553 118      553    1     HRPT  2025-07-09 16:27:30 http…
#> 4 House   H. Rept. 118-6   118      6      1     HRPT  2025-05-27 14:16:55 http…
#> 5 House   H. Rept. 118-203 118      203    1     HRPT  2025-05-27 14:16:54 http…
prints <- cong_committee_print(congress = 118, limit = 5)
prints
#> # A tibble: 5 × 5
#>   chamber congress jacket_number update_date         url                        
#>   <chr>   <chr>    <chr>         <dttm>              <chr>                      
#> 1 Senate  118      56851         2025-08-19 13:58:18 https://api.congress.gov/v…
#> 2 Senate  118      58130         2025-08-13 13:43:16 https://api.congress.gov/v…
#> 3 Senate  118      57824         2025-08-01 15:28:19 https://api.congress.gov/v…
#> 4 Senate  118      57664         2025-06-23 14:28:19 https://api.congress.gov/v…
#> 5 House   118      50700         2025-06-11 21:58:14 https://api.congress.gov/v…

To gather hearing metadata, use cong_hearing():

hearings <- cong_hearing(congress = 118, limit = 5)
hearings
#> # A tibble: 5 × 6
#>   chamber congress jacket_number number update_date         url                 
#>   <chr>   <chr>    <chr>         <chr>  <dttm>              <chr>               
#> 1 Senate  118      58988         582    2025-08-30 01:21:17 https://api.congres…
#> 2 Senate  118      60121         626    2025-08-29 01:34:15 https://api.congres…
#> 3 Senate  118      57774         524    2025-08-29 01:21:16 https://api.congres…
#> 4 Senate  118      55897         335    2025-08-28 01:21:16 https://api.congres…
#> 5 House   118      50897         <NA>   2025-08-27 01:36:18 https://api.congres…

The results can be refined by chamber or hearing number.

Executive Business

Track presidential nominations with cong_nomination():

noms <- cong_nomination(congress = 118, limit = 50)
noms
#> # A tibble: 50 × 12
#>    citation congress description       latest_action_action…¹ latest_action_text
#>    <chr>    <chr>    <chr>             <date>                 <chr>             
#>  1 PN112    118      Samuel H. Slater… 2025-01-03             Returned to the P…
#>  2 PN870    118      J. Todd Inman, o… 2024-03-08             Confirmed by the …
#>  3 PN113    118      Samuel H. Slater… 2025-01-03             Returned to the P…
#>  4 PN9      118      Phillip A. Washi… 2023-03-30             Received message …
#>  5 PN672    118      Brendan Carr, of… 2023-09-30             Confirmed by the …
#>  6 PN799    118      Andrew N. Fergus… 2024-03-07             Confirmed by the …
#>  7 PN482    118      Douglas Dziak, o… 2024-03-07             Confirmed by the …
#>  8 PN304    118      Rebecca Kelly Sl… 2024-03-07             Confirmed by the …
#>  9 PN673    118      Anna M. Gomez, o… 2023-09-07             Confirmed by the …
#> 10 PN800    118      Andrew N. Fergus… 2024-03-07             Confirmed by the …
#> # ℹ 40 more rows
#> # ℹ abbreviated name: ¹​latest_action_action_date
#> # ℹ 7 more variables: nomination_type_is_civilian <chr>, number <chr>,
#> #   organization <chr>, part_number <chr>, received_date <date>,
#> #   update_date <dttm>, url <chr>

Each row includes name, post, and status (e.g., confirmed, withdrawn).

To go deeper into an individual nomination, such as Val Deming’s nomination to the Postal Service Board of Governors, use:

nom_details <- cong_nomination(congress = 118, number = 2005)
nom_details
#> # A tibble: 1 × 18
#>   actions_count actions_url             authority_date citation committees_count
#>           <int> <chr>                   <date>         <chr>               <int>
#> 1             6 https://api.congress.g… 2025-05-12     PN2005                  1
#> # ℹ 13 more variables: committees_url <chr>, congress <int>, description <chr>,
#> #   hearings_count <int>, hearings_url <chr>, latest_action_action_date <date>,
#> #   latest_action_text <chr>, nomination_type_is_civilian <lgl>,
#> #   nominees <list>, number <int>, part_number <chr>, received_date <date>,
#> #   update_date <dttm>

Congressional Record

Use cong_daily_record() to access floor proceedings:

record <- cong_daily_record(volume = 169, issue = 1)
record
#> # A tibble: 1 × 8
#>   congress full_issue       issue_date          issue_number session_number
#>      <int> <list>           <dttm>              <chr>                 <int>
#> 1      118 <tibble [6 × 8]> 2023-01-03 05:00:00 1                         1
#> # ℹ 3 more variables: update_date <dttm>, url <chr>, volume_number <int>

To view specific speeches or statements:

articles <- cong_daily_record(volume = 169, issue = 1, item = 'articles')
articles
#> # A tibble: 3 × 2
#>   name           section_articles 
#>   <chr>          <list>           
#> 1 Daily Digest   <tibble [12 × 4]>
#> 2 House Section  <tibble [10 × 4]>
#> 3 Senate Section <tibble [17 × 4]>

Summary

congress provides programmatic access to a rich set of legislative data. This package aims to enable reproducible workflows for research on Congress. The functions in this package offer a structured and consistent interface to the Congress.gov API.

For more detail, consult the function reference at https://christophertkenny.com/congress/. If you encounter edge cases or undocumented behavior, consider opening an issue.


DISCLAIMER: This vignette has been written with help from ChatGPT 4o. It has been reviewed for correctness and edited for clarity by the package author. Please note any issues at https://github.com/christopherkenny/congress/issues.