<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Caselaw | ISSUES | The Ohio State University</title><link>https://issues-osu.github.io/ISSUESlab/tag/caselaw/</link><atom:link href="https://issues-osu.github.io/ISSUESlab/tag/caselaw/index.xml" rel="self" type="application/rss+xml"/><description>Caselaw</description><generator>Hugo Blox Builder (https://hugoblox.com)</generator><language>en-us</language><lastBuildDate>Fri, 01 Aug 2025 00:00:00 +0000</lastBuildDate><image><url>https://issues-osu.github.io/ISSUESlab/media/logo_hu2fedd529b9d9d7008e9f6968cd645fa1_199187_300x300_fit_lanczos_3.png</url><title>Caselaw</title><link>https://issues-osu.github.io/ISSUESlab/tag/caselaw/</link></image><item><title>How to Analyze Caselaw Using CourtListener's API in R</title><link>https://issues-osu.github.io/ISSUESlab/post/courtlistener-icwa-r/</link><pubDate>Fri, 01 Aug 2025 00:00:00 +0000</pubDate><guid>https://issues-osu.github.io/ISSUESlab/post/courtlistener-icwa-r/</guid><description>&lt;p>I previously showed how to pull Indian Child Welfare Act (ICWA) cases using the Caselaw Access Project (Harvard Law). That API has since changed. This post updates the workflow using the Free Law Project&amp;rsquo;s &lt;a href="https://www.courtlistener.com/" target="_blank" rel="noopener">CourtListener&lt;/a>, which now partners with Harvard to make this data freely available.&lt;/p>
&lt;hr>
&lt;h2 id="finding-the-cases">Finding the Cases&lt;/h2>
&lt;p>Start at the &lt;a href="https://www.courtlistener.com/" target="_blank" rel="noopener">CourtListener website&lt;/a> and search for &lt;strong>&amp;ldquo;Indian Child Welfare Act&amp;rdquo;&lt;/strong> (or &lt;code>&amp;quot;icwa&amp;quot;&lt;/code>). You&amp;rsquo;ll see a page of opinion results.&lt;/p>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="CourtListener website search results for ICWA" srcset="
/ISSUESlab/post/courtlistener-icwa-r/fig1_hufedd63f6ad123f7c354dd78648837004_144176_858ec2311db5cf01cf179ac1ae6254fc.webp 400w,
/ISSUESlab/post/courtlistener-icwa-r/fig1_hufedd63f6ad123f7c354dd78648837004_144176_8deecacb87864cc5f171956ae3f4fdc8.webp 760w,
/ISSUESlab/post/courtlistener-icwa-r/fig1_hufedd63f6ad123f7c354dd78648837004_144176_1200x1200_fit_q80_h2_lanczos_3.webp 1200w"
src="https://issues-osu.github.io/ISSUESlab/ISSUESlab/post/courtlistener-icwa-r/fig1_hufedd63f6ad123f7c354dd78648837004_144176_858ec2311db5cf01cf179ac1ae6254fc.webp"
width="760"
height="229"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>Click &lt;strong>Select Jurisdiction → State&lt;/strong>. Clear all, then select &lt;strong>Ohio Supreme Court&lt;/strong>, &lt;strong>Ohio Court of Appeals&lt;/strong>, and &lt;strong>Ohio Court of Claims&lt;/strong>. This gives you a quick check on the expected volume to validate the code&amp;rsquo;s output below.&lt;/p>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Subsetting the search results to Ohio courts" srcset="
/ISSUESlab/post/courtlistener-icwa-r/fig2_hu122e30f40a4ef7585c2df1ce9f5ce1f7_199812_fdd8726a5d6cf47b82e146e15dc74d97.webp 400w,
/ISSUESlab/post/courtlistener-icwa-r/fig2_hu122e30f40a4ef7585c2df1ce9f5ce1f7_199812_8e57278d18ae611a8873ca58375d7e82.webp 760w,
/ISSUESlab/post/courtlistener-icwa-r/fig2_hu122e30f40a4ef7585c2df1ce9f5ce1f7_199812_1200x1200_fit_q80_h2_lanczos_3.webp 1200w"
src="https://issues-osu.github.io/ISSUESlab/ISSUESlab/post/courtlistener-icwa-r/fig2_hu122e30f40a4ef7585c2df1ce9f5ce1f7_199812_fdd8726a5d6cf47b82e146e15dc74d97.webp"
width="760"
height="224"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>The site reported &lt;strong>36 cases&lt;/strong> from Ohio. Note that the exact number may change over time as new opinions are added or metadata is corrected.&lt;/p>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Ohio search results showing 36 opinions" srcset="
/ISSUESlab/post/courtlistener-icwa-r/fig3_hu5e88e226ba997a0358e9da868c72015b_200058_a549f31bec1e2feee89caa69dd78e31d.webp 400w,
/ISSUESlab/post/courtlistener-icwa-r/fig3_hu5e88e226ba997a0358e9da868c72015b_200058_a7534a55a8ff289dbf65610b866d76bf.webp 760w,
/ISSUESlab/post/courtlistener-icwa-r/fig3_hu5e88e226ba997a0358e9da868c72015b_200058_1200x1200_fit_q80_h2_lanczos_3.webp 1200w"
src="https://issues-osu.github.io/ISSUESlab/ISSUESlab/post/courtlistener-icwa-r/fig3_hu5e88e226ba997a0358e9da868c72015b_200058_a549f31bec1e2feee89caa69dd78e31d.webp"
width="760"
height="266"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;hr>
&lt;h2 id="getting-the-data-into-r">Getting the Data into R&lt;/h2>
&lt;p>The Search API returns clean JSON results by querying for opinions that contain the exact phrase &lt;code>&amp;quot;indian child welfare act&amp;quot;&lt;/code>, restricting to published opinions, ordering by relevance, and (optionally) limiting results to three Ohio courts.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-r" data-lang="r">&lt;span class="line">&lt;span class="cl">&lt;span class="nf">library&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">httr2&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nf">library&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">purrr&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nf">library&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">dplyr&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nf">library&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">tibble&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nf">library&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">tidyr&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nf">library&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">stringr&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">SEARCH_BASE&lt;/span> &lt;span class="o">&amp;lt;-&lt;/span> &lt;span class="s">&amp;#34;https://www.courtlistener.com/api/rest/v4/search/&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">UA&lt;/span> &lt;span class="o">&amp;lt;-&lt;/span> &lt;span class="s">&amp;#34;R/httr2 (your-email-address) – ICWA metadata collection&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">query_params&lt;/span> &lt;span class="o">&amp;lt;-&lt;/span> &lt;span class="nf">list&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">q&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s">&amp;#39;&amp;#34;indian child welfare act&amp;#34;&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">type&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s">&amp;#34;o&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">order_by&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s">&amp;#34;score desc&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">stat_Published&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s">&amp;#34;on&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">court&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s">&amp;#34;ohio ohioctapp ohioctcl&amp;#34;&lt;/span> &lt;span class="c1"># optional: specify court&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>A few helper functions keep the parsing tidy:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-r" data-lang="r">&lt;span class="line">&lt;span class="cl">&lt;span class="n">pull_chr&lt;/span> &lt;span class="o">&amp;lt;-&lt;/span> &lt;span class="kr">function&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kc">...&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">v&lt;/span> &lt;span class="o">&amp;lt;-&lt;/span> &lt;span class="n">purrr&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="nf">pluck&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kc">...&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">.default&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="kc">NA&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nf">is.null&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">v&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="nf">length&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">v&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="m">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="kr">return&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kc">NA_character_&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">as.character&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">v&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">pull_num&lt;/span> &lt;span class="o">&amp;lt;-&lt;/span> &lt;span class="kr">function&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kc">...&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">v&lt;/span> &lt;span class="o">&amp;lt;-&lt;/span> &lt;span class="n">purrr&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="nf">pluck&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kc">...&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">.default&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="kc">NA_real_&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">suppressWarnings&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nf">as.numeric&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">v&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">get_json&lt;/span> &lt;span class="o">&amp;lt;-&lt;/span> &lt;span class="kr">function&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">url&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">resp&lt;/span> &lt;span class="o">&amp;lt;-&lt;/span> &lt;span class="nf">request&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">url&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">|&amp;gt;&lt;/span> &lt;span class="nf">req_user_agent&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">UA&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">|&amp;gt;&lt;/span> &lt;span class="nf">req_url_query&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">|&amp;gt;&lt;/span> &lt;span class="nf">req_perform&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">resp_check_status&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">resp&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">resp_body_json&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">resp&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">simplifyVector&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="kc">FALSE&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This function handles pagination automatically, following the &lt;code>next&lt;/code> cursor until all pages are exhausted:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-r" data-lang="r">&lt;span class="line">&lt;span class="cl">&lt;span class="n">fetch_search_pages&lt;/span> &lt;span class="o">&amp;lt;-&lt;/span> &lt;span class="kr">function&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">req&lt;/span> &lt;span class="o">&amp;lt;-&lt;/span> &lt;span class="nf">request&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">SEARCH_BASE&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">|&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">req_user_agent&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">UA&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">|&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">req_url_query&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">!!!&lt;/span>&lt;span class="n">query_params&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">dat&lt;/span> &lt;span class="o">&amp;lt;-&lt;/span> &lt;span class="n">req&lt;/span> &lt;span class="o">|&amp;gt;&lt;/span> &lt;span class="nf">req_perform&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">|&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">(&lt;/span>&lt;span class="nf">\&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">r&lt;/span>&lt;span class="p">){&lt;/span> &lt;span class="nf">resp_check_status&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">r&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="nf">resp_body_json&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">r&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">simplifyVector&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="kc">FALSE&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">})()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">pages&lt;/span> &lt;span class="o">&amp;lt;-&lt;/span> &lt;span class="nf">list&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">dat&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">while&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="nf">is.null&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">dat&lt;/span>&lt;span class="o">$&lt;/span>&lt;span class="n">`next`&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">dat&lt;/span> &lt;span class="o">&amp;lt;-&lt;/span> &lt;span class="nf">request&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">dat&lt;/span>&lt;span class="o">$&lt;/span>&lt;span class="n">`next`&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">|&amp;gt;&lt;/span> &lt;span class="nf">req_user_agent&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">UA&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">|&amp;gt;&lt;/span> &lt;span class="nf">req_perform&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">|&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">(&lt;/span>&lt;span class="nf">\&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">r&lt;/span>&lt;span class="p">){&lt;/span> &lt;span class="nf">resp_check_status&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">r&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="nf">resp_body_json&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">r&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">simplifyVector&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="kc">FALSE&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">})()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">pages&lt;/span> &lt;span class="o">&amp;lt;-&lt;/span> &lt;span class="nf">append&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">pages&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nf">list&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">dat&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">pages&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">pages&lt;/span> &lt;span class="o">&amp;lt;-&lt;/span> &lt;span class="nf">fetch_search_pages&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">results&lt;/span> &lt;span class="o">&amp;lt;-&lt;/span> &lt;span class="n">pages&lt;/span> &lt;span class="o">|&amp;gt;&lt;/span> &lt;span class="nf">map&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;results&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">|&amp;gt;&lt;/span> &lt;span class="nf">flatten&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>results&lt;/code> is a list of per-case records from the API. Each element includes the case name, filing date, court identifiers, citation strings, a public URL where the caselaw text is available, and other metadata.&lt;/p>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="R dataframe showing key case fields: case_name, date_filed, court_name, absolute_url" srcset="
/ISSUESlab/post/courtlistener-icwa-r/fig4_hudc5134a08a65892976a37d19c679cab2_374030_2e88eef7a45bc40fa02fdff57d84c434.webp 400w,
/ISSUESlab/post/courtlistener-icwa-r/fig4_hudc5134a08a65892976a37d19c679cab2_374030_a9387f449e4d6d53fc71f30cd65bfe11.webp 760w,
/ISSUESlab/post/courtlistener-icwa-r/fig4_hudc5134a08a65892976a37d19c679cab2_374030_1200x1200_fit_q80_h2_lanczos_3.webp 1200w"
src="https://issues-osu.github.io/ISSUESlab/ISSUESlab/post/courtlistener-icwa-r/fig4_hudc5134a08a65892976a37d19c679cab2_374030_2e88eef7a45bc40fa02fdff57d84c434.webp"
width="760"
height="188"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>For Ohio, this produced ~35 unique case names versus 36 displayed on the site. Minor discrepancies happen because search hits can include multiple opinions or sibling opinions per matter, and because the index is updated over time.&lt;/p>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Unique case names returned by the API" srcset="
/ISSUESlab/post/courtlistener-icwa-r/fig5_hu3c29cd48dcbcfd9382d962e9753aa742_147152_ba89c03f91ed10def567895987722d74.webp 400w,
/ISSUESlab/post/courtlistener-icwa-r/fig5_hu3c29cd48dcbcfd9382d962e9753aa742_147152_2c0693c596b1513aa7b5080a8a1775e5.webp 760w,
/ISSUESlab/post/courtlistener-icwa-r/fig5_hu3c29cd48dcbcfd9382d962e9753aa742_147152_1200x1200_fit_q80_h2_lanczos_3.webp 1200w"
src="https://issues-osu.github.io/ISSUESlab/ISSUESlab/post/courtlistener-icwa-r/fig5_hu3c29cd48dcbcfd9382d962e9753aa742_147152_ba89c03f91ed10def567895987722d74.webp"
width="760"
height="387"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;hr>
&lt;h2 id="downloading-the-full-text">Downloading the Full Text&lt;/h2>
&lt;p>Each opinion has an API endpoint with plain-text and HTML fields. A small loop can request the text for each case URL, with a short pause and retry between requests, and save one &lt;code>.txt&lt;/code> file per opinion:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-r" data-lang="r">&lt;span class="line">&lt;span class="cl">&lt;span class="n">download_opinion_text&lt;/span> &lt;span class="o">&amp;lt;-&lt;/span> &lt;span class="kr">function&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">url&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">out_dir&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s">&amp;#34;opinions&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">dir.create&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">out_dir&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">showWarnings&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="kc">FALSE&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">slug&lt;/span> &lt;span class="o">&amp;lt;-&lt;/span> &lt;span class="nf">basename&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">url&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">path&lt;/span> &lt;span class="o">&amp;lt;-&lt;/span> &lt;span class="nf">file.path&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">out_dir&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nf">paste0&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">slug&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s">&amp;#34;.txt&amp;#34;&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">resp&lt;/span> &lt;span class="o">&amp;lt;-&lt;/span> &lt;span class="nf">request&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">url&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">|&amp;gt;&lt;/span> &lt;span class="nf">req_user_agent&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">UA&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">|&amp;gt;&lt;/span> &lt;span class="nf">req_perform&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">resp_check_status&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">resp&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">body&lt;/span> &lt;span class="o">&amp;lt;-&lt;/span> &lt;span class="nf">resp_body_json&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">resp&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">simplifyVector&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="kc">FALSE&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">text&lt;/span> &lt;span class="o">&amp;lt;-&lt;/span> &lt;span class="n">body&lt;/span>&lt;span class="o">$&lt;/span>&lt;span class="n">plain_text&lt;/span> &lt;span class="o">%||%&lt;/span> &lt;span class="n">body&lt;/span>&lt;span class="o">$&lt;/span>&lt;span class="n">html_with_citations&lt;/span> &lt;span class="o">%||%&lt;/span> &lt;span class="s">&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">writeLines&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">text&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">path&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">Sys.sleep&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="m">0.5&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="c1"># be considerate of rate limits&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">invisible&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">path&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nf">walk&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nf">map_chr&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">results&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s">&amp;#34;absolute_url&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">download_opinion_text&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Here are the Ohio ICWA cases downloaded to a local folder:&lt;/p>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Downloaded ICWA case text files on local computer" srcset="
/ISSUESlab/post/courtlistener-icwa-r/fig6_huaad99f694e56ccd893d73b61055c332d_261998_44210b1d46e71791a593d3384554425f.webp 400w,
/ISSUESlab/post/courtlistener-icwa-r/fig6_huaad99f694e56ccd893d73b61055c332d_261998_a230df0781107c333ffc62a4f068cdd4.webp 760w,
/ISSUESlab/post/courtlistener-icwa-r/fig6_huaad99f694e56ccd893d73b61055c332d_261998_1200x1200_fit_q80_h2_lanczos_3.webp 1200w"
src="https://issues-osu.github.io/ISSUESlab/ISSUESlab/post/courtlistener-icwa-r/fig6_huaad99f694e56ccd893d73b61055c332d_261998_44210b1d46e71791a593d3384554425f.webp"
width="760"
height="342"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;hr>
&lt;h2 id="visualizing-the-results">Visualizing the Results&lt;/h2>
&lt;p>You can use &lt;code>ggplot2&lt;/code> to visualize the results. Below are two examples: filings by year and volume by court.&lt;/p>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="ICWA cases filed by year, 1980–2025" srcset="
/ISSUESlab/post/courtlistener-icwa-r/fig7_hu00119959f92dd6f2ce884fccc8491311_95527_a84503cc07b50634a0a5d2d5518fdaa0.webp 400w,
/ISSUESlab/post/courtlistener-icwa-r/fig7_hu00119959f92dd6f2ce884fccc8491311_95527_51ef58d3c973c6fcc36abd3df2c07f7d.webp 760w,
/ISSUESlab/post/courtlistener-icwa-r/fig7_hu00119959f92dd6f2ce884fccc8491311_95527_1200x1200_fit_q80_h2_lanczos_3.webp 1200w"
src="https://issues-osu.github.io/ISSUESlab/ISSUESlab/post/courtlistener-icwa-r/fig7_hu00119959f92dd6f2ce884fccc8491311_95527_a84503cc07b50634a0a5d2d5518fdaa0.webp"
width="760"
height="436"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Top 25 jurisdictions by number of ICWA opinions" srcset="
/ISSUESlab/post/courtlistener-icwa-r/fig8_hu4b954f7c70532a5f2c37f702acdb9a57_335292_e7e200fd88be81aed8f9efba5ac6ad7d.webp 400w,
/ISSUESlab/post/courtlistener-icwa-r/fig8_hu4b954f7c70532a5f2c37f702acdb9a57_335292_ac1f9785b21242d986d64feee6b6db6e.webp 760w,
/ISSUESlab/post/courtlistener-icwa-r/fig8_hu4b954f7c70532a5f2c37f702acdb9a57_335292_1200x1200_fit_q80_h2_lanczos_3.webp 1200w"
src="https://issues-osu.github.io/ISSUESlab/ISSUESlab/post/courtlistener-icwa-r/fig8_hu4b954f7c70532a5f2c37f702acdb9a57_335292_e7e200fd88be81aed8f9efba5ac6ad7d.webp"
width="760"
height="394"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;hr>
&lt;h2 id="what-you-can-do-next">What You Can Do Next&lt;/h2>
&lt;p>After downloading all data — including caselaw text and metadata — you can:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Natural Language Processing&lt;/strong> — examine sentiment or common words across opinions&lt;/li>
&lt;li>&lt;strong>Topic Modeling&lt;/strong> — explore latent themes in ICWA cases using LDA or STM&lt;/li>
&lt;li>&lt;strong>Map filings by jurisdiction&lt;/strong> — visualize geographic patterns of ICWA litigation&lt;/li>
&lt;li>&lt;strong>Integrate with other sources&lt;/strong> — link to child welfare administrative data or Census indicators&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>Remember to be considerate of rate limits and to include a &lt;strong>User Agent string&lt;/strong> with your contact information in every request.&lt;/p>
&lt;/blockquote>
&lt;p>The complete workflow is available on my &lt;a href="https://github.com/" target="_blank" rel="noopener">GitHub&lt;/a>.&lt;/p>
&lt;p>&lt;strong>Happy Coding!&lt;/strong>&lt;/p></description></item></channel></rss>